【发布时间】:2013-03-26 22:34:01
【问题描述】:
我正在观看“JAX London 2011”presentation on "Modern Java Concurrency"。在 43:20 - 43:40 的时间段内,一位观众说下面代码中的 shutdown 变量应该被声明为 volatile 并且演示者同意它(并说它在前面已经指出也一样,但他们只是没有修改演示文稿)。有问题的代码是:
public abstract class QueueReaderTask implements Runnable {
private boolean shutdown = false;
protected BlockingQueue<WorkUnit<String>> lbq;
public void run() {
while (!shutdown) {
try {
WorkUnit<String> wu = lbq.poll(10, TimeUnit.MILLISECONDS);
if (wu != null) { doAction(wu.getWork()); }
} catch (InterruptedException e) {
shutdown = true;
}
}
}
public abstract void doAction(String msg);
public void setQueue(BlockingQueue<WorkUnit<String>> q) { lbq = q; }
}
我的问题:
我不认为shutdown 应该声明为volatile。
我的理由是shutdown 是Runnable 的成员,每个任务/线程都将拥有该变量的不同私有副本。那么,为什么要设为volatile?
但由于这已在 JAX 2011 中进行了讨论,因此我假设听众中有很多专业的 Java 开发人员。我不认为他们所有人都会错过这个! 那么,我错过了什么?
P.S:-
我可以理解,如果一个变量(可能)被多个线程共享,则应该声明一个变量volatile,就像在双重检查锁定模式中一样:
class Foo {
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null)
helper = new Helper();
}
}
return helper;
}
}
【问题讨论】:
标签: java multithreading volatile