[英]Java Concurrency with Sets
For the below function, I am trying to return a new Set mHashSet
that is a copy of another set iGraphicSectors
:对于下面的函数,我试图返回一个新的 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;
}
}
However line 5 mHashSet.addAll(iGraphicSectors);
然而第 5 行
mHashSet.addAll(iGraphicSectors);
is throwing a ConcurrentModificationException
(I am not sure how this is possible).正在抛出
ConcurrentModificationException
(我不确定这怎么可能)。 Is there a way I can accomplish the above task in a thread-safe manner?有没有办法以线程安全的方式完成上述任务?
What you need to do is to use a Set
that is thread-safe for iGraphicSectors
as you obviously read and modify it concurrently, the simplest way can be to use the decorator Collections.synchronizedSet(Set<T> s)
to make your current Set
thread-safe, any read and write accesses will then be automatically protected with a synchronized
block thanks to the decorator, however you still need to protect iterations over it explicitly with a synchronized
block.您需要做的是对
iGraphicSectors
使用线程安全的Set
,因为您显然是同时读取和修改它的,最简单的方法是使用装饰器Collections.synchronizedSet(Set<T> s)
来制作当前的Set
线程安全,由于装饰器,任何读取和写入访问都将使用synchronized
块自动保护,但是您仍然需要使用synchronized
块显式保护它的迭代。
Here is an example of how to create it:以下是如何创建它的示例:
Set<String> iGraphicSectors = Collections.synchronizedSet(new HashSet<String>());
Here is how your code would then look like:以下是您的代码的外观:
public Set<String> getGraphics() {
// Still needed as the constructor of LinkedHashSet will iterate
// over iGraphicSectors
synchronized (iGraphicSectors) {
return new LinkedHashSet<String>(iGraphicSectors);
}
}
From your latest comments, it sounds like you simply want to make the Set
immutable - which you can do without using any synchronization primitives with :从您的最新评论中,听起来您只是想让
Set
不可变 - 您可以在不使用任何同步原语的情况下做到这一点:
return Collections.unmodifiableSet(iGraphicSectors);
at the end of this function (See the docs ).在此函数的末尾(请参阅文档)。
As a side note, it's fairly obvious that you don't want to use synchronization, as the Set
is constructed locally within the function.作为旁注,很明显您不想使用同步,因为
Set
是在函数内部构造的。 It does not have any visibility to other threads executing in your program.它对程序中执行的其他线程没有任何可见性。 If any synchronization is to take place, it's not in this method .
如果要进行任何同步,则不在此方法中。
The real question is, will the Set
returned by this method change?真正的问题是,这个方法返回的
Set
会改变吗? If so, you can return a synchronized Set
from this function with:如果是这样,你可以从这个函数返回一个同步的
Set
:
return Collections.synchronizedSet(...)
at the end of this function (again, see the docs ).在此函数的末尾(再次参见文档)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.