同步Set线程的构造函数是否安全? [英] Is constructor-copy of a synchronized Set thread safe?

查看:152
本文介绍了同步Set线程的构造函数是否安全?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

获取 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆