【发布时间】:2020-12-26 09:59:00
【问题描述】:
也许我希望表达的不是那么清楚, 第一个案例是关于何时以及如何使用
volatile的示例,为了使程序成功运行,我们需要添加volatile。
第二个是希望表达的是,即使没有 volatile,程序也能成功运行。 我希望知道为什么在没有“volatile”的情况下会发生这种情况
在第一个示例中,使用 volatile 的典型示例
public static int num=1;
public static class MyThread extends Thread {
// flag
private boolean flag = false ;
public boolean isFlag() { return flag;}
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) { e.printStackTrace();
}
// change flag to true
this.flag = true ;
System.out.println("flag=" + flag);
this.flag=true;
}
}
// main
static void testWithOutVolatile(){
MyThread t=new MyThread();
t.start();
while(true) {
boolean is=t.flag;
if (is) {
System.out.println("run======");
}
}
}
启动后,除非使用volatile,否则主线程不会发现flag的变化
但是,在示例中,意外地,thread2 得到了 flag 的变化,为什么会发生这种情况?
static int amb=0;
static void testSimple(){
Thread t1=new Thread(()->{
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
amb++;
});
Thread t2=new Thread(()->{while(true) {
if (amb == 0) {
System.out.println("no");
}
if (amb != 0) {
System.out.println("SUc");
break;
}
}});
t2.start();
t1.start();
}
然后试了一下,发现如果我删除了代码
if (amb == 0) {
System.out.println("no");
}
它会按我想的那样运行,thread2 无法获取更改。
谢谢你的回答,QwQ
【问题讨论】:
-
老实说我不明白你的问题,但让我澄清一些事情。为了让变量在 Java 中的多个线程之间(实时)共享其状态,它需要是 Volatile。使用静态变量:它们在线程之间共享,但在一个线程中所做的更改可能不会立即对另一个线程可见,这使得变量看起来像是有两个副本。 stackoverflow.com/questions/13582395/…xspdf.com/resolution/52087767.html
-
对不起,可能我希望表达的不是那么清楚,第一个案例是关于何时以及如何使用
volatile的示例,为了让程序成功运行,我们需要添加挥发性的。第二个是希望表达,即使没有 volatile,程序也能成功运行。我希望知道为什么在没有“volatile”的情况下会发生这种情况 -
实际上,@SusanMustafa - 严格来说,它需要
volatile并不完全正确。还有其他方法。例如,适当地使用synchronized,或使用AtomicXxx类型,或使用final字段。 -
@StephenC 是的斯蒂芬,也许我的评论可能会让人觉得这是唯一的方法,但是我确实给出了一个示例 stackoverflow 以进行更多说明。
-
@StephenC hhh,谢谢,感觉很好:P
标签: java thread-safety volatile