繁体   English   中英

Java 并发与集合

[英]Java Concurrency with Sets

对于下面的函数,我试图返回一个新的 Set mHashSet ,它是另一个集合iGraphicSectors的副本:

public Set<String> getGraphics() {
    synchronized (iGraphicSectors) {  // class variable of type Set<String>
        LinkedHashSet<String> mHashSet = new LinkedHashSet<String>();
        synchronized (mHashSet) {
            mHashSet.addAll(iGraphicSectors);
        }
        return mHashSet;
    }
}

然而第 5 行mHashSet.addAll(iGraphicSectors); 正在抛出ConcurrentModificationException (我不确定这怎么可能)。 有没有办法以线程安全的方式完成上述任务?

您需要做的是对iGraphicSectors使用线程安全的Set ,因为您显然是同时读取和修改它的,最简单的方法是使用装饰器Collections.synchronizedSet(Set<T> s)来制作当前的Set线程安全,由于装饰器,任何读取和写入访问都将使用synchronized块自动保护,但是您仍然需要使用synchronized块显式保护它的迭代。

以下是如何创建它的示例:

Set<String> iGraphicSectors = Collections.synchronizedSet(new HashSet<String>());

以下是您的代码的外观:

public Set<String> getGraphics() {
    // Still needed as the constructor of LinkedHashSet will iterate
    // over iGraphicSectors 
    synchronized (iGraphicSectors) {  
        return new LinkedHashSet<String>(iGraphicSectors);
    }
}

从您的最新评论中,听起来您只是想让Set不可变 - 您可以在不使用任何同步原语的情况下做到这一点:

return Collections.unmodifiableSet(iGraphicSectors);

在此函数的末尾(请参阅文档)。

作为旁注,很明显您不想使用同步,因为Set是在函数内部构造的。 它对程序中执行的其他线程没有任何可见性。 如果要进行任何同步,则不在此方法中

真正的问题是,这个方法返回的Set会改变吗? 如果是这样,你可以从这个函数返回一个同步的Set

return Collections.synchronizedSet(...)

在此函数的末尾(再次参见文档)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM