我有一个 ArrayList 'X',它被传递给多个线程,每个线程使用 addAll() 向这个 ArrayList 'X' 添加更多数据。显然这里存在多线程问题,一种选择是使代码的 addAll() 部分“同步”(或)使用 copyOnWriteArrayList。
但我的问题是,声明这个 ArrayList 'volatile' 会达到同样的目的吗?JVM 是否相应地对这些读/写指令进行排序并防止多线程问题?
我有一个 ArrayList 'X',它被传递给多个线程,每个线程使用 addAll() 向这个 ArrayList 'X' 添加更多数据。显然这里存在多线程问题,一种选择是使代码的 addAll() 部分“同步”(或)使用 copyOnWriteArrayList。
但我的问题是,声明这个 ArrayList 'volatile' 会达到同样的目的吗?JVM 是否相应地对这些读/写指令进行排序并防止多线程问题?
声明这个 ArrayList 'volatile' 会达到同样的目的吗?
你实际上不能。当你写
volatile ArrayList list;
这使得list
引用易变,而不是底层的 ArrayList。这也意味着当你做
list.add(x);
被list
读取,所以你只得到一个读屏障而不是写屏障。
注意:这不会使操作成为您真正需要的原子操作,但是如果没有写屏障,您甚至可能在另一个线程中看不到此操作。
JVM 是否相应地对这些读/写指令进行排序并防止多线程问题?
它将相应地对读取进行排序,但在这种情况下不会以可用于避免多线程问题的方式进行排序。也就是说,没有办法让这个工作与 volatile 一起工作,更不用说假设 JVM 会做你想做的事而不必担心它。
synchronized
通过比较可以正确使用。你仍然可能弄错,这不是万无一失的,但你很有可能把它弄对。
不, volatile 在这里不起作用。Volatile 关键字只是确保每次读取操作始终获得最新的更新值。这里需要用到同步。