相关疑难解决方法(0)

通过Collections.synchronizedSet(...).forEach()的迭代是否保证是线程安全的?

我们知道,默认情况下迭代并发集合不是线程安全的,所以不能使用:

Set<E> set = Collections.synchronizedSet(new HashSet<>());
//fill with data
for (E e : set) {
    process(e);
}
Run Code Online (Sandbox Code Playgroud)

这是因为在迭代期间可能会添加数据,因为没有排他锁set.

这在javadoc中描述Collections.synchronizedSet:

public static Set synchronizedSet(Set s)

返回由指定集支持的同步(线程安全)集.为了保证串行访问,必须通过返回的集完成对后备集的所有访问.

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

Set s = Collections.synchronizedSet(new HashSet());
...
synchronized (s) { Iterator i = s.iterator(); // Must be in the synchronized block while (i.hasNext()) foo(i.next()); }

不遵循此建议可能会导致非确定性行为.

然而,这并不适用于Set.forEach,它继承了默认的方法forEachIterable.forEach.

现在我查看了源代码,在这里我们可以看到我们有以下结构:

  1. 我们要求一个Collections.synchronizedSet().
  2. 我们得到一个:

    public static <T> Set<T> synchronizedSet(Set<T> s) {
        return new SynchronizedSet<>(s); …
    Run Code Online (Sandbox Code Playgroud)

java collections thread-safety java-8

27
推荐指数
2
解决办法
4460
查看次数

标签 统计

collections ×1

java ×1

java-8 ×1

thread-safety ×1