問題引出:
今天在看volatile的時候,自己寫了個例子,
發現即使沒有volatile,我程式也照常跑了
描述
首先看看這個情況的描述
第一個代碼是有關何時以及如何使用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變數的更改

但是如果下面這段代碼,程式他,竟然看到了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();
}
問題的解決
自己動手修改了一下代碼嘗試了一下,
發現如果洗掉print,執行緒就看不到變化,
只要隨隨便便加一個print陳述句,執行緒就看到了變化
Thread t2=new Thread(()->{while(true) {
System.out.println("no");
if (amb != 0) {
System.out.println("SUc");
break;
}
}});

問題似乎變的清晰了,點開print的代碼,
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
這里有一個synchronized ,synchronized大家都知道吧,重量級鎖,執行緒將釋放資源等待
執行緒執行到這里時,釋放了自己的資源,發生了“執行緒切換”,執行緒的緩沖區就隨之消失,
等到第二次執行到這里的時候,重新獲取了變數的值
所以看起來似乎不用使用“volatile”
更多文章,看https://blog.csdn.net/weixin_44494373
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/240994.html
標籤:java
上一篇:一.初識Java
