inq*_*One 3 java multithreading volatile
我正在阅读关于"Modern Java Concurrency"的"JAX London 2011" 演讲.在持续时间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; }
}
Run Code Online (Sandbox Code Playgroud)
我的问题:我不认为shutdown
应该宣布volatile
.我的理由是,shutdown
作为a的成员Runnable
,每个任务/线程都将拥有该变量的不同私有副本.那么,为什么要成功volatile
呢?
但是由于在JAX 2011中对此进行了讨论,我假设在该受众中有许多专家Java开发人员.我不认为所有人都会错过这个!那么,我错过了什么?
PS: - 我可以理解,如果变量volatile
(可能)由多个线程共享,则应声明该变量,如Double-Checked-Locking模式:
class Foo {
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null)
helper = new Helper();
}
}
return helper;
}
}
Run Code Online (Sandbox Code Playgroud)
每个任务/线程将具有该变量的不同私有副本.那么,为什么要让它"不稳定"呢?
你是正确的,如果该shutdown
布尔只从内修改QueueReaderTask
实例.在这种情况下shutdown
,只有一个线程修改,不需要volatile
.
坦率地说,代码看起来很奇怪.为什么要捕获InterruptedException
,设置shutdown
布尔值,然后循环并退出.为什么现在只做以下事情?为什么要shutdown
举旗?
while (true) {
try {
WorkUnit<String> wu = lbq.poll(10, TimeUnit.MILLISECONDS);
if (wu != null) { doAction(wu.getWork()); }
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
Run Code Online (Sandbox Code Playgroud)
也许在帖子中删除了额外的代码?如果没有,我想知道这是否是复制并粘贴在一个更大的代码段中,在代码调用中也shutdown
设置为true .
PS: - 我可以理解,如果变量(可能)由多个线程共享,则应将其声明为"volatile",如Double-Checked-Locking模式:
对.一个典型的模式是shutdown
从另一个线程修改,它告诉线程停止处理.在那种情况下,它需要volatile
.
归档时间: |
|
查看次数: |
219 次 |
最近记录: |