在关于synchronizedMap的教程中,我遇到了以下代码(来自教程的注释):
Map m = Collections.synchronizedMap(new HashMap());
...
Set s = m.keySet(); // Needn't be in synchronized block
...
synchronized(m) { // Synchronizing on m, not s!
Iterator i = s.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}我在源代码中看到,迭代器方法不是由同步节包装的。没问题的。
我害怕得到意想不到的东西
Set s = m.keySet();
// Could happen something unexpected here ?
synchronized(m) { 请澄清为什么这段代码是安全的?
synchronized(m) { // Synchronizing on m, not s!
Set s = m.keySet(); // Needn't be in synchronized block
Iterator i = s.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}这种同步是否过度了?
发布于 2014-05-27 15:52:52
虽然Collections.synchronizedMap()保证包装的map上的每个操作都是线程安全的,但它并不保证在其上迭代是线程安全的。当您在迭代的同时在map上同步时,您就保证了当一个线程在map上迭代时,另一个线程不能访问它(毕竟,您希望确保您以原子的方式迭代它)。
如果没有这种同步,另一个线程可能会在i.hasNext() while循环之间执行一个或多个操作。
其实现是synchronizedMap()包装器在集合本身上同步(在您的代码m中),因此使用synchronized(m)获取对象监视器可以确保在完成迭代之前,另一个线程无法访问它。
https://stackoverflow.com/questions/23883684
复制相似问题