同步Set线程的构造函数是否安全?

mor*_*ano 4 java

获取java.util.Set的同步版本的最简单方法是使用Collections.synchronizedSet(),如下所示:

Set mySyncSet = Collections.synchronizedSet(new HashSet());
Run Code Online (Sandbox Code Playgroud)

Java的API说,有关这个新的对象:

当迭代它时,用户必须手动同步返回的集合

我的问题是,如果我使用这样的复制构造函数创建此Set的副本:

Set mySetCopy = new HashMap(mySyncSet);
Run Code Online (Sandbox Code Playgroud)

它是线程安全的吗?(不是HashMap构造函数使用迭代来获取Set的成员吗?)或者我应该手动同步这样的操作?:

Set mySetCopy;

synchronized(mySyncSet) {
    mySetCopy = new HashMap(mySyncSet);
}
Run Code Online (Sandbox Code Playgroud)

Bor*_*der 9

让我们来看看代码:

public HashSet(Collection<? extends E> c) {
    map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
    addAll(c);
}
Run Code Online (Sandbox Code Playgroud)

所以只是打电话addAll,

public boolean addAll(Collection<? extends E> c) {
    boolean modified = false;
    for (E e : c)
        if (add(e))
            modified = true;
    return modified;
}
Run Code Online (Sandbox Code Playgroud)

所以这会循环Collection你给它.

答案是否定的,构造函数副本不是线程安全的.

在将其传递给构造函数之前,您需要使用第二个选项并对其进行显式synchronized操作Set.