volatile能保证线程安全吗?这个 ArrayList 例子

Does volatile guarantee thread safety? This ArrayList example

我有一个传递给多个线程的 ArrayList 'X',其中每个线程使用 addAll() 将更多数据添加到此 ArrayList 'X'。显然这里存在多线程问题,一种选择是使代码的 addAll() 部分 'synchronized' (或)使用 copyOnWriteArrayList.

但我的问题是,声明这个 ArrayList 'volatile' 会达到同样的目的吗? JVM 是否相应地对这些 read/write 指令进行排序并防止多线程问题?

不,volatile 在这里不起作用。 volatile 关键字只是确保每次读取操作总是获得最新的更新值。这里需要使用synchronized.

would declaring this ArrayList 'volatile' achieve the same purpose?

实际上你不能。当你写

volatile ArrayList list;

这使得 list 引用易变,而不是底层 ArrayList。这也意味着当你做

list.add(x);

list 是读的,所以你只得到一个读屏障而不是写屏障。

注意:这不会使操作成为您真正需要的原子操作,但如果没有写屏障,您甚至可能不会在另一个线程中看到此操作。

Does JVM order these read/write instructions accordingly and prevent multi-threading issues?

它会相应地对读取进行排序,但在这种情况下不会以可用于避免多线程问题的方式进行排序。即没有办法使它与 volatile 一起工作,更不用说假设 JVM 会做你想做的事而不必担心它。

synchronized比较可以正确使用。你仍然可以做错,这不是万无一失的,但你有很大的机会做对。