java - 为什么我们在这里特别说 ArrayList 不是线程安全的?

标签 java multithreading collections

描述:如果我们在多个线程中使用相同的对象引用,则没有对象是线程安全的。类似地,如果任何集合引用在多个线程之间共享,则该集合不是线程安全的,因为其他线程可以访问它。那么,为什么我们在这里特别说 ArrayList 不是线程安全的呢?其他集合呢?

最佳答案

您误解了“线程安全”的含义。

当我们说“类 X 是线程安全的”时,我们并不是不必担心以下程序的线程安全性:使用它。如果您只使用线程安全对象来构建程序,那么不能保证您的程序是线程安全的。

那么它能保证什么?

假设您有一个列表。假设两个线程 A 和 B 分别向列表中的同一索引写入不同的值,假设某个线程 C 从该索引读取数据,并假设这三个线程都不使用任何同步。

如果列表是“线程安全的”,那么您可以放心,线程 C 将获得三个可能值之一:

  • 线程 A 写入的值,
  • 线程 B 写入的值,
  • 线程 A 或线程 B 写入之前存储在该索引处的值。

如果列表不是线程安全的,那么这三件事中的任何一个都可能发生,而且还可能发生其他事情:

  • 线程 C 可以获得一个从未在列表中的值,
  • 即使没有其他线程继续使用该列表,线程 C 将来的行为也可能会出现问题,
  • 程序可能会崩溃,
  • 等等。 (我不知道还会发生多少奇怪的事情。)

当我们说一个类是“线程安全的”时,我们是说它总是以可预测的、合理的方式运行,即使它的方法被多个线程同时调用。

如果您编写一个使用“线程安全”列表的程序,并且它依赖于线程 C 读取我上面列出的三种可能性中的一个特定值,那么您的程序有一个线程安全问题,即使列表本身没有。

关于java - 为什么我们在这里特别说 ArrayList 不是线程安全的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61078300/

相关文章:

java - JScrollPane 不显示 JPanel

java - 无法在 "/usr/bin/java/bin/java"(-1) 找到可执行文件

java线程池任务超时问题

java - 在java中剪切字符串而不破坏单词的中间

javascript - 如何编写不阻塞 ui 的 Javascript 代码

c# - 代码块中的最大 n 个线程

Java 8 流并从调用 boolean 方法设置属性

java - 将列表的第一个元素移动到末尾

c# - 调用 Clear 是否也会处理这些项目?

java - 没有找到合适的方法