并发迭代和线程安全

时间:2016-01-07 06:45:01

标签: java multithreading

我正在阅读B. Goetz Java Concurrency In Practice现在我在关于线程安全集合的部分。他描述了所谓的隐藏迭代器&#34;这可能会抛出public class HiddenIterator{ @GuardedBy("this") private final Set<Integer> set = new HashSet<Integer>(); public synchronized void add(Integer i){ set.add(i); } public synchronized void remove(Integer i){ set.remove(i); } public void addTenThings(){ Random r = new Random(); for(int i = 0; i < 10; i++) add(r.nextInt()); System.out.println("DEBUG: added ten elements to set " + set) } } 。以下是他发布的例子:

addTenThings()

现在,ConcurrentModificationException可能会抛出set,因为打印set的内容涉及迭代它。但他提出以下建议来处理它:

  

如果HiddenIterator使用synchronizedSet包装HashSet,   封装同步,不会发生这种错误。

我不太明白。即使我们将NotThreadSafe包装到synchronized-wrapper中,该类仍将保持{{1}}。他是什么意思?

1 个答案:

答案 0 :(得分:6)

这是因为Collections.synchronizedSet同步每个方法,包括toString。实际上,如果你试图迭代一个包装的手动,你可以获得ConcurrentModificationException,所以你必须自己同步手动迭代。但是做隐藏迭代的方法已经做到了,所以你至少不必担心这一点。以下是JDK源代码中的相应代码:

public String toString() {
    synchronized (mutex) {return c.toString();}
}

此处,mutex在包装类的构造函数中初始化为this,因此它基本上是synchronized (this)