同步Set线程的构造函数是否安全? [英] Is constructor-copy of a synchronized Set thread safe?
问题描述
获取 java.util.Set 的同步版本的最简单方法是使用 Collections.synchronizedSet(),如下所示:
The easiest way to get a synchronized version of a java.util.Set would be using Collections.synchronizedSet() like this:
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 使用这样的复制构造函数:
My question is, if I create a copy of this Set using a copy constructor like this:
Set mySetCopy = new HashMap(mySyncSet);
它是线程安全的吗? (不是HashMap构造函数使用迭代来获取 Set 的成员吗?)或者我应该手动同步这样的操作?:
Wil it be thread-safe? (isn't HashMap constructor using iteration to get members of Set after all?) or should I manually synchronize the operation like this?:
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
你给它。
So this loops over the Collection
you give it.
因此答案是否定的,构造函数副本不线程安全。
The answer is therefore no, constructor copy is not thread safe.
您需要使用第二个选项并在传递 Set
之前执行显式同步
它进入构造函数。
You need to use your second option and do a explicit synchronized
on the Set
before passing it into the constructor.
这篇关于同步Set线程的构造函数是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!