可以安全地在Collections.synchronizedX的结果上调用Java 8 Collection默认方法吗?

时间:2015-10-06 11:00:05

标签: java java-8

Java 8在集合框架中的接口上添加了大量默认方法;但是,Collections.synchronizedX方法的JavaDoc几乎没有改变。我不清楚在他们返回的结果上调用新的默认方法是否安全?

我检查了Oracle JDK源代码,它们似乎被重写为线程安全的,但是对所有JDK都有保证吗?

1 个答案:

答案 0 :(得分:3)

OpenJDK / OracleJDK中的实际状态如下:

  • 新的spliterator()stream()parallelStream()方法未同步,必须在外部手动同步(类似于之前存在的iterator()listIterator() )。

  • 其他新方法已同步,包括forEachremoveIfreplaceAllsortgetOrDefaultputIfAbsent,{{ 1}},replacecomputeIfAbsentcomputeIfPresentcompute

这种行为实际上是specified

  

当通过mergeIteratorSpliterator

遍历返回的集合时,用户必须手动同步

所以你可以期望除了这些明确提到的异常之外的任何其他方法都是同步的。微妙的问题是它只为Stream指定,但没有为其他方法指定,并且未明确指定,例如,synchronizedCollectionsynchronizedList继承了某些行为(尽管实际上它是)。

请注意,synchronizedCollectionforEach等批量处理方法在整个迭代过程中都会占用一个监视器,因此您最终有机会安全地迭代/更新整个集合。但是,您应该知道可能存在死锁/饥饿,因为收集可能会长时间锁定。

另请注意,当前状态会引入replaceAllsyncCollection.forEach(...)之间的差异:第二个呼叫未同步。

更新:我reported向OpenJDK开发人员提交了syncCollection.stream().forEach(...)方法的规范,并且submitted a patch已被JDK-9接受。< / p>