Java 8向集合框架中的接口添加了大量默认方法;然而,Collections.synchronized方法的Collections.synchronized几乎没有改变。在我看来,不清楚对它们返回的结果调用新的默认方法是否安全?
我检查了Oracle JDK源代码,它们似乎被重写为线程安全,但是所有JDK都有任何保证吗?
发布于 2015-10-06 12:15:05
OpenJDK/OracleJDK中事物的真实状态如下:
spliterator()、stream()和parallelStream()方法不是同步的,必须在外部手动同步(类似于以前存在的iterator()或listIterator() )。forEach、removeIf、replaceAll、sort、getOrDefault、putIfAbsent、replace、computeIfAbsent、computeIfPresent、compute、merge。这样的行为实际上是规定。
在通过
Iterator、Spliterator或Stream遍历返回的集合时,用户必须手动同步它。
因此,您可以预期,除了这些显式提到的异常之外,任何其他方法都是同步的。微妙的问题是,它只是为synchronizedCollection指定的,而不是为其他方法指定的,并且没有明确指定,例如,synchronizedList继承了synchronizedCollection的一些行为(尽管实际上确实如此)。
注意,像forEach或replaceAll这样的批量处理方法在整个迭代过程中保持一个监视器,所以您最终有机会安全地迭代/更新整个集合。但是,您应该注意到可能存在死锁/饥饿,因为集合可能会被锁定很长时间。
还请注意,当前状态引入了syncCollection.forEach(...)和syncCollection.stream().forEach(...)之间的区别:第二个调用是不同步的。
UPDATE:i 已报告给OpenJDK开发人员,synchronizedXXX方法的规范必须更新,提交补丁被JDK-9所接受。
https://stackoverflow.com/questions/32968295
复制相似问题