您好,登錄后才能下訂單哦!
本篇內容介紹了“java線程之Happens before規則是什么”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
happens-before 規定了對共享變量的寫操作對其它線程的讀操作可見,它是可見性與有序性的一套規則總結,拋開以下 happens-before 規則,JMM 并不能保證一個線程對共享變量的寫,對于其它線程對該共享變量的讀可見.
線程解鎖 m 之前對變量的寫,對于接下來對 m 加鎖的其它線程對該變量的讀可見
static int x; static Object m = new Object(); new Thread(()->{ synchronized(m) { x = 10; } },"t1").start(); new Thread(()->{ synchronized(m) { System.out.println(x); } },"t2").start(); /* 運行結果: 10 */
線程對 volatile 變量的寫,對接下來其它線程對該變量的讀可見
volatile static int x; new Thread(()->{ x = 10; },"t1").start(); new Thread(()->{ System.out.println(x); },"t2").start(); /* 運行結果: 10 */
線程 start 前對變量的寫,對該線程開始后對該變量的讀可見
static int x; x = 10; new Thread(()->{ System.out.println(x); },"t2").start(); /* 運行結果: 10 */
線程結束前對變量的寫,對其它線程得知它結束后的讀可見(比如其它線程調用 t1.isAlive() 或 t1.join()等待 它結束)
static int x; Thread t1 = new Thread(()->{ x = 10; },"t1"); t1.start(); t1.join(); System.out.println(x); /* 運行結果: 10 */
線程 t1 打斷 t2(interrupt)前對變量的寫,對于其他線程得知 t2 被打斷后對變量的讀可見(通過 t2.interrupted 或 t2.isInterrupted)
static int x; public static void main(String[] args) { Thread t2 = new Thread(()->{ while(true) { if(Thread.currentThread().isInterrupted()) { System.out.println(x); break; } } },"t2"); t2.start(); new Thread(()->{ sleep(1); x = 10; t2.interrupt(); },"t1").start(); while(!t2.isInterrupted()) { Thread.yield(); } System.out.println(x); } /* 運行結果: 10 */
對變量默認值(0,false,null)的寫,對其它線程對該變量的讀可見
static int a; public static void main(String[] args) { new Thread(()->{ System.out.println(a); }).start(); } /* 運行結果: 0 */
具有傳遞性,如果 x hb-> y 并且 y hb-> z 那么有 x hb-> z ,配合 volatile 的防指令重排,有下面的例子
volatile static int x; static int y; new Thread(()->{ y = 10; x = 20; },"t1").start(); new Thread(()->{ // x=20 對 t2 可見, 同時 y=10 也對 t2 可見 System.out.println(x); },"t2").start(); /* 運行結果: 20 */
“java線程之Happens before規則是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。