国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術文章
文章詳情頁

多線程 - 關于Java內存可見性的問題

瀏覽:120日期:2023-12-02 08:39:19

問題描述

請看以下代碼

public class TestVolatile {public static void main(String[] args) throws InterruptedException {ThreadDemo td = new ThreadDemo();new Thread(td).start();Thread.sleep(1);while(true){ if(td.isFlag()){System.out.println('------------------');break; }} }}class ThreadDemo implements Runnable { private boolean flag = false; @Override public void run() {try { Thread.sleep(200);} catch (InterruptedException e) {}flag = true;System.out.println('flag=' + isFlag()); } public boolean isFlag() {return flag; } public void setFlag(boolean flag) {this.flag = flag; }}

把Thread.sleep(1)換成Thread.sleep(1000)就能獲取flag修改后的值,即td.isFlag()返回true。雖然看了Java內存模型的概念,但我不知道如何解釋這段代碼,誰能解釋一下?

相關問題: Java多線程的工作內存是什么?

問題解答

回答1:

你得先說說你的預期效果是啥?問問題要問清楚啊

回答2:

這個期待是沒有規范支撐的。代碼中沒有做任何能保證 '子線程寫 happen-before 主線程讀' 的事情。

sleep(1000)后看到修改只是巧合,一個JVM如果在更久后才讓主線程看到,甚至永遠不讓主線程看到都不違反規范。

回答3:

你的程序應該是想測試 volatile 關鍵字的功能。但是 “把 Thread.sleep(1) 換成 Thread.sleep(1000) 就能獲得預期效果” 這樣做理解上是不對的。首先,程序中總共有兩個線程,主線程(暫稱 線程M)和 new Thread(td) (暫稱 線程T)。

當寫 Thread.sleep(1) 的時候,線程M 在 1ms 之后,便開始在 while(true) 循環中檢查 td.isFlag() 的值,但是因為內存可見性的關系,線程M 并不能及時讀取 線程T 中 flag 的值,所以此時導致了死循環;

當寫 Thread.sleep(1000) 的時候,M 在 1000ms 之后,開始在 while(true) 循環中檢查 td.isFlag() 的值;但是 T 在 200ms 的時候,便將 flag 的值設為 true 了,所以,M 在 1000ms 之后檢測 td.isFlag() 的值肯定是返回 true 的,那么第一次判斷便會返回 true,產生輸出并跳出 while(true) 循環。

為了讓 線程M 及時讀取到 線程T 中 flag 的值,需要將 flag 使用 volatile 關鍵字進行修飾:

private volatile boolean flag = false;

那么每次對 flag 的修改,其他線程都立馬可見。關于 volatile 的使用,可以參考我的博客:Java 多線程(6):volatile 關鍵字的使用

回答4:

可以參考如下三個代碼:其中第一個和你的情況一樣,由于多線程的可見性問題,可能導致無限循環下去。第二個是使用synchronized解決此問題,大多數工作場景用這個好第三個是使用volatile解決,但這個關鍵字只保證可見性,在實際場景中局限性比較大,得慎用

public class StopThread {private static boolean stopRequested;public static void main(String[] args) throws InterruptedException {Thread backgroundThread = new Thread(new Runnable() {@Override public void run() {@SuppressWarnings('unused')int i = 0;while(!stopRequested) {// System.out.println('加上這一句程序就可以終止,否則無限循環下去'); i++;} }});backgroundThread.start();TimeUnit.SECONDS.sleep(1);stopRequested = true; }}

public class StopThread2 {private static boolean stopRequested;public static synchronized boolean getStopRequested() {return stopRequested; }public static synchronized void requestStop() {stopRequested = true; }public static void main(String[] args) throws InterruptedException {Thread backgroundThread = new Thread(new Runnable() {@Override public void run() {@SuppressWarnings('unused')int i = 0;while(!getStopRequested()/* stopRequested */) { i++;} }});backgroundThread.start();TimeUnit.SECONDS.sleep(1);requestStop();/* stopRequested = true; */ }}

public class StopThread3 {private static volatile boolean stopRequested; public static void main(String[] args) throws InterruptedException {Thread backgroundThread = new Thread(new Runnable() {@Override public void run() {@SuppressWarnings('unused')int i = 0;while(stopRequested) { i++;} }});backgroundThread.start();TimeUnit.SECONDS.sleep(1);stopRequested = true; }}

標簽: java
相關文章:
主站蜘蛛池模板: 国产成人在线视频观看 | 成年人网站免费视频 | 美女张开腿黄网站免费国产 | 精品亚洲大全 | 99av视频| 亚洲午夜精品一级在线播放放 | 国产精品亚洲午夜不卡 | 黄色毛片a | 亚洲免费不卡 | 亚洲日本免费 | 成人毛片全部免费观看 | 97se亚洲综合在线 | 另类专区另类专区亚洲 | 日本三级香港三级人妇99 | 中文字幕在线看视频一区二区三区 | 美女又黄又免费的视频 | 欧美日韩在线视频 | 欧美国产成人在线 | 波多野结衣aⅴ在线 | 欧美日韩一级黄色片 | 欧美激情毛片裸推荐 | 国产一区二区成人 | 亚洲欧美一级久久精品 | 亚洲一区二区三区福利在线 | 亚洲成a人片 | 5x性区m免费毛片视频看看 | 中文字幕亚洲一区二区三区 | 午夜在线视频一区二区三区 | 久草a在线 | 亚洲免费成人在线 | 乱子伦xxxx | 91人成亚洲高清在线观看 | 乱子伦农村xxxx视频 | 精品特级一级毛片免费观看 | 久草免费资源站 | 日本一线a视频免费观看 | 日韩欧美中文字幕在线观看 | 国产日本欧美高清免费区 | 黄色三级网站在线观看 | 国产91成人精品亚洲精品 | 久草在线新视频 |