说明volatile:此代码是线程安全的吗? [英] illustrating volatile : is this code thread-safe?
问题描述
我试图用一个例子来说明volatile
的用法和重要性,如果省略volatile
,它实际上不会给出很好的结果.
I'm trying to illustrate the use and importance of volatile
with an example that would really not give a good result if volatile
was omitted.
但是我不太习惯使用volatile
.以下代码的想法是,如果省略volatile
,则会导致无限循环;如果存在volatile
,则将是完全线程安全的.以下代码是线程安全的吗?您是否还有其他使用volatile
的逼真的简短示例代码,如果没有该示例,则会给出明显不正确的结果?
But I'm not really used to using volatile
. The idea of the following code is to cause an infinite loop if volatile
is omitted, and be perfectly thread-safe if volatile
is present. Is the following code thread-safe? Do you have any other realistic and short example of code that uses volatile
and would give an obviously incorrect result without it?
代码如下:
public class VolatileTest implements Runnable {
private int count;
private volatile boolean stopped;
@Override
public void run() {
while (!stopped) {
count++;
}
System.out.println("Count 1 = " + count);
}
public void stopCounting() {
stopped = true;
}
public int getCount() {
if (!stopped) {
throw new IllegalStateException("not stopped yet.");
}
return count;
}
public static void main(String[] args) throws InterruptedException {
VolatileTest vt = new VolatileTest();
Thread t = new Thread(vt);
t.start();
Thread.sleep(1000L);
vt.stopCounting();
System.out.println("Count 2 = " + vt.getCount());
}
}
推荐答案
Victor是正确的,您的代码存在问题:原子性和可见性.
Victor is right, there are issues with your code: atomicity and visibility.
这是我的版本:
private int count;
private volatile boolean stop;
private volatile boolean stopped;
@Override
public void run() {
while (!stop) {
count++; // the work
}
stopped = true;
System.out.println("Count 1 = " + count);
}
public void stopCounting() {
stop = true;
while(!stopped)
; //busy wait; ok in this example
}
public int getCount() {
if (!stopped) {
throw new IllegalStateException("not stopped yet.");
}
return count;
}
}
如果某个线程观察到stopped==true
,则可以保证工作已完成并且结果可见.
If a thread observes that stopped==true
, it's guaranteed that the work completes and the result is visible.
从易失性写入到易失性读取(在同一变量上)之间存在先发生后关联,因此如果有两个线程
There is a happens-before relation from volatile write to volatile read (on the same variable), so if there are two threads
thread 1 thread 2
action A
|
volatile write
\
volatile read
|
action B
动作A在动作B之前发生; B中可以看到A中的内容.
action A happens-before action B; writes in A are visible by B.
这篇关于说明volatile:此代码是线程安全的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!