您好,登錄后才能下訂單哦!
這篇文章主要為大家展示了“java多線程Synchronized如何實現可見性”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“java多線程Synchronized如何實現可見性”這篇文章吧。
要實現共享變量的可見性,必須保證兩點:
線程修改后的共享變量值能夠及時從工作內存刷新到主內存中
其他線程能夠及時把共享變量的最新值從主內存更新到自己的工作內存中
synchronized
volatile
synchronized能夠實現:
原子性(同步)
可見性
JMM關于synchronized的兩條規定:
1.線程解鎖前,必須把貢獻變量的最新值刷新到主內存中
2.線程加鎖時,將清空工作內存中共享變量的值,從而使用共享變量時需要從主內存中重新讀取最新的值(注意:加鎖與解鎖需要同一把鎖)
線程解鎖前對共享變量的修改在下次加鎖時對其他線程可見
獲取互斥鎖
清空工作內存
從主內存拷貝變量的最新副本到工作內存
執行代碼
將更改后的共享變量的值刷新到主內存
釋放互斥鎖
代碼書寫的順序與實際執行的順序不同,指令重排序是編譯器或處理器為了提高程序性能而做得優化
編譯器優化的重排序(編譯器優化)
指令級并行重排序(處理器優化)
內存系統的重排序(處理器優化)
as-if-serial:無論如何重排序,程序執行的結果應該與代碼順序執行的結果一致(Java編譯器、運行時和處理器都會保證Java在單線程下遵循as-if-serial語義)
public class SynchronizedTest { /** * 共享變量 */ private boolean ready = false; private int result = 0; private int number = 1; /** * 寫操作 */ public void write(){ ready = true;//1.1 number = 2;//1.2 } /** * 讀操作 */ public void read(){ if(ready){//2.1 result=number*3;//2.2 } System.out.println("result的值為:"+result); } /** * 內部線程類 */ private class ReadWriteThread extends Thread{ //根據構造方法中傳入的flag參數,確定線程執行讀操作還是寫操作 private boolean flag; public ReadWriteThread(boolean flag){ this.flag=flag; } @Override public void run() { if(flag){ //構造方法中傳入true,執行寫操作 write(); }else{ //構造方法中傳入false,執行讀操作 read(); } } } public static void main(String[] args) { SynchronizedTest synchronizedTest = new SynchronizedTest(); //啟動線程執行寫操作 synchronizedTest.new ReadWriteThread(true).start(); //啟動線程執行讀操作 synchronizedTest.new ReadWriteThread(false).start(); } }
1.線程的交叉執行
eg:上述程序執行步驟為1.1-》2.1-》2.2-》1.2
eg:上述程序執行步驟為1.2-》2.1-》2.2-》1.1
2.重排序結合線程交叉執行
eg: 2.1和2.2重排序后
int mid = number*3; if(ready){ result=mid; }
共享變量更新后的值沒有在工作內存與主內存間及時更新
public class SynchronizedTest { /** * 共享變量 */ private boolean ready = false; private int result = 0; private int number = 1; /** * 寫操作 */ public synchronized void write(){ ready = true;//1.1 number = 2;//1.2 } /** * 讀操作 */ public synchronized void read(){ if(ready){//2.1 result=number*3;//2.2 } System.out.println("result的值為:"+result); } /** * 內部線程類 */ private class ReadWriteThread extends Thread{ //根據構造方法中傳入的flag參數,確定線程執行讀操作還是寫操作 private boolean flag; public ReadWriteThread(boolean flag){ this.flag=flag; } @Override public void run() { if(flag){ //構造方法中傳入true,執行寫操作 write(); }else{ //構造方法中傳入false,執行讀操作 read(); } } } public static void main(String[] args) { SynchronizedTest synchronizedTest = new SynchronizedTest(); //啟動線程執行寫操作 synchronizedTest.new ReadWriteThread(true).start(); //啟動線程執行讀操作 synchronizedTest.new ReadWriteThread(false).start(); } }
以上是“java多線程Synchronized如何實現可見性”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。