获取 java.util.Set 同步版本的最简单方法是使用 Collections.synchronizedSet(),如下所示:
Set mySyncSet = Collections.synchronizedSet(new HashSet());
Java API说到这个新对象:
It is imperative that the user manually synchronize on the returned set when iterating over it
我的问题是,如果我使用这样的复制构造函数创建此 Set 的副本:
Set mySetCopy = new HashMap(mySyncSet);
它会是线程安全的吗? (毕竟 HashMap 构造函数不是使用迭代来获取 Set 的成员吗?)还是我应该像这样手动同步操作?:
Set mySetCopy;
synchronized(mySyncSet) {
mySetCopy = new HashMap(mySyncSet);
}
最佳答案
让我们看一下代码:
public HashSet(Collection<? extends E> c) {
map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
addAll(c);
}
这样就调用addAll
,
public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
所以这会遍历你给它的 Collection
。
因此答案是否定的,构造函数副本不是线程安全的。
在将 Set
传递给构造函数之前,您需要使用第二个选项并在 Set
上执行显式 synchronized
。
关于java - 同步 Set 线程的构造函数副本是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17616784/