java - 不同的不同线程修改共享列表的不同索引

标签 java concurrency synchronized thread-synchronization

X 个不同的线程修改 X 个列表的不同索引或者基本上 X 个不同的线程修改 是一个好的设计X 共享对象的不同属性。我考虑过使用synchronized/synchronizedList(任何并发数据结构),但我想避免随之而来的性能开销。该方法是否取决于 X 的值?

根据 this添加到单个 arraylist 的多个线程是否可行,但这不是一个好的设计,它与此相同吗?

如果答案因语言而异,我特别询问 JAVA,但想知道为什么不同的语言有不同的答案。

最佳答案

如果我们假设您的列表具有固定的初始大小,比方说 10 个元素,并且您有 10 个线程处理元素 1 到 10,则不涉及共享相互状态(参见 shared mutual state is the root of all evil)。因此,我认为同步没有什么大问题,并且会使用该列表。

但是请记住,这在很大程度上取决于执行的操作和列表的大小。如果列表中有 1000000 个元素,创建 1000000 个线程将是低效甚至不可能的。

此外,一旦您开始从列表中添加和删除元素,您就将列表本身作为共享的相互状态,您现在必须担心同步问题。

编辑:关于共享相互状态

如果您共享的状态不是相互的,那么同步就不会有问题,因为任何人都无法更改数据。

如果你有不共享的相互状态,你可以改变状态,但除了你当前的代码之外没有人可以在状态上工作, 因此更改直接反射(reflect)在您的代码中。

如果您共享相互状态,您现在可以有两个线程,每个线程都可以更改另一个线程的数据。在多线程中的顺序 只要您不应用同步或锁定等机制,这种变化发生的地方和读者反射(reflect)的变化就不是确定性的。 因此,您可能会遇到如下经典问题:

  • A 从元素 x 中读取数据并进行转换。
  • B 从元素 x 中读取数据并对其进行转换 <-- A 尚未写入其更改,因此 B 使用过时的数据
  • A向元素x写入数据
  • B 写道 元素 x 的数据 <-- A 的更改丢失了

关于java - 不同的不同线程修改共享列表的不同索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49147153/

相关文章:

java - 未从资源获取绝对文件路径

Java:多个线程通过同步方法同时访问变量递减静态变量

java - 只有一个同步点是否有可能出现死锁?

java - @Transactional 和调用两个或多个表的逻辑应该放在哪里?

java - 对 Java 9 的 Hibernate 支持

java - 在回收者 View 中选择单个复选框

multithreading - 处理并发读取?

java - 这段代码是线程安全的吗?

Java Executor 在上一个 Callable 完成后执行一个 Callable?

java - 我是否必须同步访问 Java 中封装的线程安全数据结构?