首頁  >  文章  >  Java  >  java線程之Happens before規則是什麼

java線程之Happens before規則是什麼

WBOY
WBOY轉載
2023-04-14 19:07:101374瀏覽

正文

happens-before 規定了對共享變數的寫入操作對其它線程的讀取操作可見,它是可見性與有序性的一套規則總結,拋開以下happens-before 規則,JMM 並不能保證一個線程對共享變量的寫,對於其它線程對該共享變量的讀取可見.

案例1

線程解鎖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
*/

案例2

#線程對volatile 變數的寫,對接下來其它線程對該變數的讀取可見

    volatile static int x;
    new Thread(()->{
     x = 10;
    },"t1").start();

    new Thread(()->{
     System.out.println(x);
    },"t2").start();
/*
运行结果:
10
*/

案例3

線程start 前對變數的寫,對該線程開始後對該變數的讀取可見

static int x;
x = 10;
new Thread(()->{
 System.out.println(x);
},"t2").start();
/*
运行结果:
10
*/

案例4

線程結束前對變數的寫,對其它線程得知它結束後的讀可見(比如其它線程調用t1.isAlive() 或t1.join()等待它結束)

static int x;
Thread t1 = new Thread(()->{
 x = 10;
},"t1");
t1.start();
t1.join();
System.out.println(x);
/*
运行结果:
10
*/

案例5

線程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
*/

案例6

對變數預設值(0,false,null)的寫,對其它線程對該變數的讀可見

    static int a;
    public static void main(String[] args) {
        new Thread(()->{
            System.out.println(a);
        }).start();

    }
/*
运行结果:
0
*/

案例7

具有傳遞性,如果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規則是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除