1

基于以下答案:我仍然不清楚: concurrentMap 上的同步构造有什么作用,如果有的话。即在并发映射的情况下,同步(映射)与非同步之间有什么区别。我对解决方案的正确性或相信的优点不感兴趣。只是对这个问题的回答: 问:在 concurrentmap 上同步和不同步有什么区别?特别是关于性能..就足够了。请不要再说什么了。
我只对发生的事情感兴趣,没有补充建议。

我有一个理论问题,我正在解决一些心理问题:假设我有一个并发集合类 say=>ConcurrentHashMap 映射;

假设我有三种方法:

method1: synchronized(map){
       doSomethingWithThemap(); //Assume put integers 1.. 1000000
}

method2:doSomethingWithThemap(); //Note it is not synchronized 
method3:doSomethingElseWithThemap(); //Assume put integers 2000000.. 3000000

现在假设 2 个测试用例:


  • TestCase1:产生两个线程A和B。A调用method1,B调用method3。
  • TestCase2:产生两个线程 A' 和 B'。A'调用method2,B'调用method3。

从性能的角度来看,我希望 TestCase2 获胜,因为据我了解,在 TestCase1 中,B 无法添加到地图中,尽管是并发的,因为同步块将持有地图上的锁,而在测试用例 2。

我的单元测试不验证这个假设。

问:我在这里缺少什么。即给定并发集合上的同步块是否会影响性能?

4

4 回答 4

2

问:我在这里缺少什么。

您对自身进行内部同步的假设ConcurrentHashMap是不正确的:根据源代码,实现使用java.util.concurrent.locks对象,其实例隐藏在集合中,因此您无法锁定/同步它们。

一般来说,这是类库编写者应该遵循的建议:如果您需要在对象上同步,请不要在 上同步this;在您的类中创建一个私有对象,然后在该对象上进行同步。否则,您可能会面临其他人在您的对象上同步导致的并发问题,并且无限期地持有锁。

于 2012-05-02T00:10:49.667 回答
0

您无法保证 ConcurrentHashMap 将其实例用作监视器。它可能非常使用其他一些对象来锁定!

private Object lock = new Object();

synchronized(lock) {
   // do some stuff - you can't get my lock because it is private
}

ConcurrentHashMap 甚至有可能不使用锁,而是使用其他一些并发原语,如比较和设置、信号量等。

Java 中的锁是可重入的,所以如果你已经持有锁,你就不会阻塞自己。

于 2012-05-02T00:14:49.700 回答
0

ConcurrentHashMap 没有使用同步...虽然仍然是线程安全的,但是例如 get 调用并没有锁定任何东西。并发数据结构非常好和有趣。好吧,它在某些情况下确实使用了一些内部锁定,但没有暴露任何东西,当然也不会暴露对象的监视器本身。

顺便一提。像这样测量并发代码性能相当棘手,并且会因运行和计算机而异,但无论如何都存在缺陷。

但是,如果您改用同步的哈希图,理论上它可以像您描述的那样工作。Collections.synchronizedMap(yourMap);

于 2012-05-02T00:18:01.423 回答
0
What does the synchronized construct on the concurrentMap do, if anything

它只是浪费时间和空间。ConcurrentMap已经体现了处理并发的替代方法。

于 2012-05-02T10:07:58.347 回答