Java 8在集合框架中的接口上添加了大量默认方法;但是,Collections.synchronizedX
方法的JavaDoc几乎没有改变。我不清楚在他们返回的结果上调用新的默认方法是否安全?
我检查了Oracle JDK源代码,它们似乎被重写为线程安全的,但是对所有JDK都有保证吗?
答案 0 :(得分:3)
OpenJDK / OracleJDK中的实际状态如下:
新的spliterator()
,stream()
和parallelStream()
方法未同步,必须在外部手动同步(类似于之前存在的iterator()
或listIterator()
)。
其他新方法已同步,包括forEach
,removeIf
,replaceAll
,sort
,getOrDefault
,putIfAbsent
,{{ 1}},replace
,computeIfAbsent
,computeIfPresent
,compute
。
这种行为实际上是specified:
当通过
遍历返回的集合时,用户必须手动同步merge
,Iterator
或Spliterator
所以你可以期望除了这些明确提到的异常之外的任何其他方法都是同步的。微妙的问题是它只为Stream
指定,但没有为其他方法指定,并且未明确指定,例如,synchronizedCollection
从synchronizedList
继承了某些行为(尽管实际上它是)。
请注意,synchronizedCollection
或forEach
等批量处理方法在整个迭代过程中都会占用一个监视器,因此您最终有机会安全地迭代/更新整个集合。但是,您应该知道可能存在死锁/饥饿,因为收集可能会长时间锁定。
另请注意,当前状态会引入replaceAll
和syncCollection.forEach(...)
之间的差异:第二个呼叫未同步。
更新:我reported向OpenJDK开发人员提交了syncCollection.stream().forEach(...)
方法的规范,并且submitted a patch已被JDK-9接受。< / p>