使用Java ReentrantLock时,是否需要在变量中添加volatile?

时间:2018-11-14 09:00:55

标签: java multithreading

我从 Java8 Condition 看下面的代码,并且有一个问题:

由于方法put()take()可能被多个线程同时调用,因此我们需要在变量中添加 volatile 以获得正确的方法价值吗?

例如:
对于数组items,如果两个线程调用put()向其中添加元素,而另一个线程调用take()从中获取元素,则在某些情况下{{1 }}是否无法从主存储器中获取最新数据? 程序如何确保线程调用take()始终具有正确的take()大小?

items

1 个答案:

答案 0 :(得分:2)

诸如volatile之类的关键字很浅。就像finalstaticprivate适用于更改对数组的引用时一样,更改数组的内容也未涵盖。

例如代替

Object[] array;

array[0] = "hello";

如果您更改为final

final Object[] array;

array[0] = "hello"; // I can still alter the array referrenced

如果您更改为volatile

volatile Object[] array;

array = new Object[1]; // a write barrier is added as I wrote to array
array[0] = "hello"; // I didn't change the array reference so no write barrier
  

由于put()和take()方法可能被多个线程同时调用,我们是否需要为变量添加volatile以获取正确的值?

正确使用ReeentrantLock将添加您需要的读/写障碍。