Gil*_*ili 5 java collections thread-safety
自 2008 年起,Stackoverflow 上就有许多 问题询问不可修改的集合是否是线程安全的,但 JDK 10(2018 年发布)引入了一个不同的野兽:现有集合的不可修改副本。
如果给定的 Collection 随后被修改,则返回的 List 将不会反映此类修改。
这是否意味着 , , 的返回值List.copyOf()都是Set.copyOf()线程Map.copyOf()安全的?
(我意识到集合中包含的元素本身不能保证是线程安全的。)
List.of(\xe2\x80\xa6)由于通过例如或创建的集合List.copyOf(\xe2\x80\xa6)不反映对指定数组或集合的后续更改,并且通常是不可变的,因此在构造之后并且在没有并发修改的情况下不可能执行修改,因此可以\x80\x99 不会有任何线程安全问题。
剩下的问题是这些馆藏的建设本身是否不受不安全出版的影响。通常,您应该使用正确的构造将对象发布到其他线程,而不是依赖于不安全的发布。
\n但回想一下,不可修改的列表说
\n\n\n\n
\n- 它们是不可修改的。无法添加、删除或替换元素。调用 List 上的任何 mutator 方法总是会导致
\nUnsupportedOperationException抛出异常。但是,如果所包含的元素本身是可变的,则可能会导致列表的内容看起来发生变化。\xe2\x80\xa6
\n\n
\n- 它们是基于价值的。
\n
沿着基于价值的链接,我们发现:
\n\n\n基于价值的课程
\n某些类(例如
\njava.lang.Integer和java.time.LocalDate)是基于值的。基于值的类具有以下属性:\n
\n- 该类仅声明最终实例字段(尽管这些字段可能包含对可变对象的引用);
\n\xe2\x80\xa6
\n
Final 字段对于旨在免受不安全发布影响的不可变对象非常重要。如JLS\xc2\xa717.5。final字段语义指定:
\n\n\n
final字段还允许程序员无需同步即可实现线程安全的不可变对象。线程安全的不可变对象被所有线程视为不可变,即使使用数据争用在线程之间传递对不可变对象的引用也是如此。这可以提供安全保证,防止错误或恶意代码滥用不可变类。
但我们仍然必须假设意图 \xe2\x80\x9c 在 JDK 开发人员\xe2\x80\x99s 端实现线程安全的不可变对象\xe2\x80\x9d,而不是例如通过显式使用字段来让开发人员感到惊讶的final意图然后故意破坏安全保障。
如有疑问,请使用安全出版物。它不会伤害\xe2\x80\x99。
\n即使您已经说过这一点,重要的是要强调,如果所包含的元素是可变的,则这不适用于它们。
\n| 归档时间: |
|
| 查看次数: |
118 次 |
| 最近记录: |