【发布时间】:2010-12-26 11:38:52
【问题描述】:
我试图弄清楚下面的代码是否存在任何潜在的并发问题。具体来说,与易失性变量相关的可见性问题。 Volatile 定义为:这个变量的值永远不会被线程本地缓存:所有的读写都会直接进入“主存”
public static void main(String [] args)
{
Test test = new Test();
// This will always single threaded
ExecutorService ex = Executors.newSingleThreadExecutor();
for (int i=0; i<10; ++i)
ex.execute(test);
}
private static class Test implements Runnable {
// non volatile variable in question
private int state = 0;
@Override
public void run() {
// will we always see updated state value? Will updating state value
// guarantee future run's see the value?
if (this.state != -1)
this.state++;
}
}
对于上述单线程执行器:
可以使 test.state 非易失性吗?换句话说,每个连续的 Test.run() (这将顺序发生而不是同时发生,因为再次执行器是单线程的),总是看到更新的 test.state 值?如果不是,是否退出 Test.run() 确保本地线程所做的任何更改都被写回主内存?否则,如果不是在线程退出时,本地所做的更改何时会被写回主内存?
【问题讨论】:
-
你从哪里得到这个定义的。听起来像是 1.5 之前的 JMM 定义(无法实现)。
-
重要的是要意识到当线程完成
Test.run()时,线程不会终止,并且关于线程在终止之前写入的值被刷新到主内存的任何保证都不适用。调用Test.run()的run()方法线程只是一个循环,它会阻塞直到它接收到要执行的新任务。当该任务从 itsrun()方法返回时,线程阻塞直到下一个任务;它不会终止(从而刷新其状态)。 -
这个 q/a 的选民是错误的。由于线程开始/结束的发生之前的关系,代码是安全的。请参阅下面的回复。
-
你知道吗?在 10 个线程总共调用 this.state++ 1000 次后,this.state 的值可能小于 1000?我不确定您是否只是没有询问此并发问题,还是没有意识到。
标签: java concurrency multithreading volatile