当前位置:  开发笔记 > 编程语言 > 正文

并发迭代和线程安全

如何解决《并发迭代和线程安全》经验,为你挑选了1个好方法。

我正在阅读B. Goetz Java Concurrency In Practice,现在我正处于关于线程安全集合的部分.他描述了可能抛出的所谓"隐藏的迭代器" ConcurrentModificationException.以下是他发布的例子:

public class HiddenIterator{

    @GuardedBy("this")
    private final Set set = new HashSet();

    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的内容涉及迭代而抛出.但他提出以下建议来处理它:

如果HiddenIterator使用synchronizedSet包装HashSet,封装同步,则不会发生此类错误.

我不太明白.即使我们包装set成同步包装器,该类仍将保留NotThreadSafe.他的意思是什么?



1> Sergei Tache..:

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

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

这里,在包装类的构造函数中mutex初始化this,所以它基本上是synchronized (this).


是的我知道.我只是在评论,并没有突出显示它是一个错误:)
推荐阅读
135369一生真爱_890
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有