首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java并发集

Java并发集
EN

Stack Overflow用户
提问于 2017-01-12 18:01:39
回答 2查看 297关注 0票数 1

对于下面的函数,我尝试返回一个新集mHashSet,它是另一个集iGraphicSectors的副本。

代码语言:javascript
复制
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 (我不确定这是怎么可能的)。是否有办法以线程安全的方式完成上述任务?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-01-12 18:23:33

您需要做的是对Set使用线程安全的iGraphicSectors,因为您显然是同时读取和修改它,最简单的方法可以是使用装饰器Collections.synchronizedSet(Set s)使当前的Set线程安全,然后任何读和写访问都将通过synchronized块自动受到保护,这要归功于装饰器,但是您仍然需要使用synchronized块显式地保护对它的迭代。

下面是一个如何创建它的示例:

代码语言:javascript
复制
Set<String> iGraphicSectors = Collections.synchronizedSet(new HashSet<String>());

下面是代码的外观:

代码语言:javascript
复制
public Set<String> getGraphics() {
    // Still needed as the constructor of LinkedHashSet will iterate
    // over iGraphicSectors 
    synchronized (iGraphicSectors) {  
        return new LinkedHashSet<String>(iGraphicSectors);
    }
}
票数 1
EN

Stack Overflow用户

发布于 2017-01-12 18:24:21

从您最近的评论中,听起来您只是想使Set不可变--无需使用任何同步原语就可以做到:

代码语言:javascript
复制
return Collections.unmodifiableSet(iGraphicSectors);

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

顺便提一句,很明显,您不想使用同步,因为Set是在函数中本地构造的。它对程序中执行的其他线程没有任何可见性。如果要进行任何同步,则不在此方法中。

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

代码语言:javascript
复制
return Collections.synchronizedSet(...)

在这个函数的末尾(同样,请参阅文档 )。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41619977

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档