使用 ConcurrentHashMap 可以消除数据可见性问题吗?
我已经通读了 Java 并发实践,并留下了这个问题:当我使用 ConcurrentHashMap 时,什么数据本书第一部分中讨论的并发问题我还需要担心吗?以下是我的一个程序中的几个示例:
1.交易者的当前仓位(共享整数,其中“整数”是数学术语)
此数字代表交易者
对象当前拥有的内容并定义其状态。它必须读取其位置才能知道要做什么(寻找开始一个新位置,或管理当前位置)。 Trader
方法在自己的线程上运行。
经纪人
对象负责设置交易者
的头寸。每次执行交易者的订单之一时,它都会设置头寸。 Broker
方法在自己的线程上运行。
交易者
和经纪商
都在同一个包中。位置被实现为包私有静态ConcurrentHashMap
。键是交易者对象的 ID。值为整数。
包的外部是应用程序。它通过公共 getter 间接获取交易者的头寸。
位置最多每隔几分钟改变一次,因此经纪人
不会经常接触地图。然而,交易者
和应用程序会经常阅读。此外,我们经常有几个交易者同时阅读地图。
因此,以这种方式使用 ConcurrentHashMap,我不必考虑锁定和数据可见性? ConcurrentHashMap 负责一切?
2.市场(买价、卖价、最新价格)
与仓位的情况几乎相同,只是现在经纪商
会非常频繁地更新价格(在繁忙时间每秒最多更新 10 次;通常每秒几次)。 交易者
和应用程序仍然会频繁读取。映射键现在是指示哪个股票或期货的代码,而值是保存市场价格的对象。
它看起来工作正常,但是在阅读 JCIP 后,我意识到如果没有正确实现,程序仍然可能被破坏。这本书讨论了 ConcurrentHashMap,但没有明确告诉我第一部分中的哪些问题我们不再需要手动解决。在这种情况下,似乎我不需要同步
任何内容。这是正确的吗?
I've read through Java Concurrency in Practice and am left with this question: when I use a ConcurrentHashMap, what data concurrency issues discussed in Part One of the book do I still need to worry about? Here are a couple of examples from one of my programs:
1. Current position of a trader (a shared integer where 'integer' is the mathematical term)
This number represents what a trader
object currently owns and defines its state. It must read its position to know what to do (look to start a new position, or manage the current one). Trader
methods run on their own thread.
A broker
object is in charge of setting the trader
's position. It will set the position each time one of the trader's orders is filled. Broker
methods run on their own thread.
Both the trader
and broker
are in the same package. Position is implemented as a package-private static ConcurrentHashMap
. The keys are id's of the trader objects. The values are Integer.
External to the package is the application. It gets the traders' positions indirectly with a public getter.
Positions will change at most once every few minutes, so the broker
won't touch the map very often. However, the trader
and application will frequently read. In addition we often have several traders reading the map concurrently.
So using a ConcurrentHashMap this way, I don't have to work about locking and data visibility? The ConcurrentHashMap takes care of everything?
2. The market (bid, ask, last prices)
Pretty much the same situation as position, except now the broker
will very frequently update the prices (up to 10 updates a second during busy times; normally a few times a second). The trader
and application still do frequent reads. The map keys now are codes indicating which stock or future, and the values are objects which hold the market prices.
It seems to work okay, but after reading JCIP, I realize the program can still be broken if things are not implemented correctly. The book talks about the ConcurrentHashMap but doesn't explicitly tell me what issues from Part I we no longer have to address manually. It appears that I don't have to synchronize
anything in this case. Is that correct?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这取决于地图中的内容,如果我正确地阅读了您的示例,情况看起来像这样
如果是这样的话,那么是的,所有并发都会得到处理。
但是,如果映射看起来像
“这不是线程安全的”,即使 ConcurrentHashMap 在放置时锁定,此时对象的所有并发访问都必须处理自己的同步。
This depends on what is in the Map, if I read your example correctly the situation looks like this
If that is the case, then yes all the concurrency is taken care of.
However if the map looks like
This is NOT thread safe, even though the ConcurrentHashMap locks when you put, all concurrent access of objects at this point must handle their own synchronization.
是的,ConcurrentHashMap 负责可见性和锁定,只要:
get/put/putIfAbsent
。Yes,
ConcurrentHashMap
takes care of visibility and locking as long as:get/put/putIfAbsent
.除非您谈论的是每秒超过 100,000 次更新/读取(非常粗略的指南),否则我不会考虑使用多个线程。原因是线程安全组件比非线程安全组件花费的时间要长很多倍。因此,如果一个组件需要 5 倍的时间才能实现线程安全,那么您需要同时使用 5 个以上的线程才能实现收支平衡,更不用说速度更快了。
当要执行相对昂贵的操作时,多线程会更有用。作为一个线程更新头寸或价格要高效得多。
Unless you are talking about over 100,000 updates/reads per second (very rough guide) I wouldn't consider using multiple threads. The reason is that thread-safe components take many times longer than components which are not. So if a component take 5x longer to be thread safe, you need to be using over 5 threads concurrently to break even, never mind go faster.
Multiple threads are much more useful when you have relatively expensive operations to perform. Updating a position or price is much more efficient as one thread.