使用 ConcurrentHashMap 可以消除数据可见性问题吗?

2024-01-09

我已读完Java 并发实践 http://www.javaconcurrencyinpractice.com/剩下的问题是:当我使用 ConcurrentHashMap 时,我还需要担心本书第一部分中讨论的哪些数据并发问题?以下是我的一个程序中的几个示例:

1. 交易者当前持仓(共享整数,其中“整数”是数学术语)

这个数字代表什么trader对象当前拥有并定义其状态。它必须读取其位置才能知道要做什么(寻找开始一个新位置,或管理当前位置)。Trader方法在自己的线程上运行。

A broker对象负责设置trader的立场。每次执行交易者的订单之一时,它都会设置头寸。Broker方法在自己的线程上运行。

这俩trader and broker位于同一个包中。位置作为包私有实现static ConcurrentHashMap。键是交易者对象的 ID。值为整数。

包的外部是应用程序。它通过公共 getter 间接获取交易者的头寸。

位置最多每隔几分钟改变一次,因此broker不会经常碰地图。但是,那trader并且应用程序会经常阅读。此外,我们经常有几个交易者同时阅读地图。

因此,以这种方式使用 ConcurrentHashMap,我不必考虑锁定和数据可见性? ConcurrentHashMap 负责一切?

2. 市场(买价、卖价、最新价格)

与位置几乎相同的情况,除了现在broker将非常频繁地更新价格(在繁忙时间每秒最多更新 10 次;通常每秒更新几次)。这trader并且应用程序仍然进行频繁的读取。映射键现在是指示哪个股票或期货的代码,而值是保存市场价格的对象。

它似乎工作正常,但在阅读 JCIP 后,我意识到如果没有正确实现,程序仍然可能被破坏。这本书讨论了 ConcurrentHashMap,但没有明确告诉我第一部分中的哪些问题我们不再需要手动解决。它appears我不必synchronize在这种情况下的任何事情。那是对的吗?


所以以这种方式使用 ConcurrentHashMap, 我不必费力去锁定和 数据可见性?并发哈希映射 照顾一切?

这取决于地图中的内容,如果我正确地阅读了您的示例,情况如下所示

static final ConcurrentMap<Integer,Integer> map = ...

class Trader{

  public int doRead(){
      map.get(someId);
   }
}
class Broker{
   public void doWrite(){
      map.put(someId,someValue);
   }
}

如果是这种情况,那么是的,所有并发都会得到处理。

但是如果地图看起来像

static final ConcurrentMap<Integer,Trader> map = ..

    class Broker{
       public void doWrite(){
          map.get(someId).setPosition(somePosition);
       }
    }

这不是线程安全的,即使 ConcurrentHashMap 在放置时锁定,此时对象的所有并发访问都必须处理自己的同步。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 ConcurrentHashMap 可以消除数据可见性问题吗? 的相关文章

随机推荐