英文:
Is it safe to use ConcurrentHashMap for things like balance storage
问题
以下是翻译好的部分:
你好,我在查看 Java 8 中的 ConcurrentHashMap
(CHM)源代码时发现,get 方法是无锁的。它只是从节点数组中进行了 volatile 读取,以从主内存中读取最新的值。
假设我有两个线程,它们使用相同的键从映射中读取和写入。采用无锁方法,读取线程不会等待,而写入线程会更新值。在这种情况下,我不能将 CHM 用于像余额存储这样的事情,因为读取器必须等待写入器才能看到最新的余额。如果 CHP 确实以这种方式工作(读取器不等待写入器),那么 Java 核心是否提供了一种使用类似于 ReadWriteLock 的东西来进行 get 和 put 操作的映射实现?类似于当 Map 对特定段进行 get 操作时,它会在此段上获取读取锁,这不会阻塞该段的其他读取器。而 put 操作将在此段上获取写锁,这将阻塞该段的读取器。
英文:
Good day, I was looking at the source code of ConcurrentHashMap
(CHM) in Java 8 and found that method get is lock free. It just makes a volatile read from the array of nodes in order to read the latest value from main memory.
Let's say that I have two threads which read and write from map using the same key. With lock free approach reader thread won't wait while writer will update the value. In this case I can't use CHM for things like balances storage because reader has to wait for writer in order to see the latest balance. If CHP really works this way(reader doesn't wait for writer) then does Java core provide a map implementation that uses things like ReadWriteLock for get and put operations? Something like when Map makes a get on specific segment then it acquires read lock on this segment which won't block other readers of this segment. And put will acquire write lock on this segment which will block readers of this segment
答案1
得分: 3
当读者和写者尝试访问相同的易失性位置时,会发生两种情况之一:要么读者会读取该值,然后写者会更新它,要么写者会首先更新该值,然后读者会读取它。
如果使用锁,同样的情况也成立。如果写操作受锁的保护,那么读取易失性值时就不需要ReadWriteLock。无论使用何种同步方法,一旦读取了值,另一个线程都可以修改它。
对于您描述的情景(余额),关键部分是读取-操作-写入,这需要一个锁或原子加法。
英文:
When both a reader and a writer attempt to access the same volatile location, one of two things will happen: either the reader will read the value and then the writer will update it, or the writer will first update the value and then the reader will read it.
The same thing is also true if you use locks. A ReadWriteLock is unnecessary for reading a volatile value if writes are protected by a lock. Regardless of the synchronization method used, once a value is read it can be modified by another thread.
For the scenario you describe (the balances), the critical section is read-operate-write, which needs a lock, or an atomic add.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论