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
比较可以正确使用。你仍然可以做错,这不是万无一失的,但你有很大的机会做对。
我有一个传递给多个线程的 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
比较可以正确使用。你仍然可以做错,这不是万无一失的,但你有很大的机会做对。