基于以下答案:
我还不清楚:如果有的话,concurrentMap上的synchronized构造会做什么。即,在并发映射的情况下,如果在同步(映射)与非同步之间存在差异,则有什么区别。 我对解决方案的正确性或相信的好处不感兴趣 。只是回答这个问题:
问:在并发映射上同步和不在同步映射上同步有什么区别?特别是关于性能..就足够了。没事了。
我只对所发生的事情感兴趣而且没有补充建议。
我有一个理论问题,我解决了一些心理问题: 假设我有一个Concurrent Collection类say => ConcurrentHashMap map;
假设我有三种方法:
method1: synchronized(map){
doSomethingWithThemap(); //Assume put integers 1.. 1000000
}
method2:doSomethingWithThemap(); //Note it is not synchronized
method3:doSomethingElseWithThemap(); //Assume put integers 2000000.. 3000000
现在假设2个TestCases:
从性能的角度来看,我希望TestCase2能够获胜,因为根据我的理解,在TestCase1中B不能添加到地图中,尽管是并发的,因为synchronized块会锁定地图,这不是TestCase2中的情况。
我的单元测试不要验证这个假设。
问:我在这里错过了什么。即,并发收集的同步块是否会影响性能?答案 0 :(得分:2)
问:我在这里缺少什么。
您ConcurrentHashMap
内部同步的假设不正确:根据the source code,实现使用java.util.concurrent.locks
个对象,其实例隐藏在集合中,因此您无法锁定/同步它们。
一般来说,这是类库的编写者应遵循的建议:如果需要在对象上进行同步,请不要在this
上进行同步;在类中创建一个私有对象,并在该对象上进行同步。否则,您可能会遇到由对象上的其他人同步引起的并发问题,并无限期地持有锁。
答案 1 :(得分:0)
您无法保证ConcurrentHashMap将其实例用作监视器。它可能会使用其他一些对象来锁定!
private Object lock = new Object();
synchronized(lock) {
// do some stuff - you can't get my lock because it is private
}
ConcurrentHashMap甚至可能不使用锁,而是使用其他一些并发原语,如比较和设置,信号量等。
Java中的锁是可重入的,因此如果您已经锁定,则不会阻止自己。
答案 2 :(得分:0)
ConcurrentHashMap没有使用synchronized ...虽然仍然是线程安全的,但是get调用例如没有锁定任何东西。并发数据结构非常好用且有趣。那么它确实在某些情况下使用了一些内部锁定,但没有暴露任何东西,当然也没有暴露对象的监视器本身。
顺便说一下。像这样测量并发代码性能相当棘手,并且因运行和运行而异,但无论如何都是有缺陷的。但是否则它理论上可以像你描述的那样使用同步的hashmap。 Collections.synchronizedMap(yourMap);
答案 3 :(得分:0)
What does the synchronized construct on the concurrentMap do, if anything
它只会浪费时间和空间。 ConcurrentMap
已经体现了处理并发的替代方法。