java線程之Happens before規(guī)則案例詳解
正文
happens-before 規(guī)定了對(duì)共享變量的寫操作對(duì)其它線程的讀操作可見,它是可見性與有序性的一套規(guī)則總結(jié),拋開以下 happens-before 規(guī)則,JMM 并不能保證一個(gè)線程對(duì)共享變量的寫,對(duì)于其它線程對(duì)該共享變量的讀可見.
案例1
線程解鎖 m 之前對(duì)變量的寫,對(duì)于接下來(lái)對(duì) m 加鎖的其它線程對(duì)該變量的讀可見
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();
/*
運(yùn)行結(jié)果:
10
*/
案例2
線程對(duì) volatile 變量的寫,對(duì)接下來(lái)其它線程對(duì)該變量的讀可見
volatile static int x;
new Thread(()->{
x = 10;
},"t1").start();
new Thread(()->{
System.out.println(x);
},"t2").start();
/*
運(yùn)行結(jié)果:
10
*/
案例3
線程 start 前對(duì)變量的寫,對(duì)該線程開始后對(duì)該變量的讀可見
static int x;
x = 10;
new Thread(()->{
System.out.println(x);
},"t2").start();
/*
運(yùn)行結(jié)果:
10
*/
案例4
線程結(jié)束前對(duì)變量的寫,對(duì)其它線程得知它結(jié)束后的讀可見(比如其它線程調(diào)用 t1.isAlive() 或 t1.join()等待 它結(jié)束)
static int x;
Thread t1 = new Thread(()->{
x = 10;
},"t1");
t1.start();
t1.join();
System.out.println(x);
/*
運(yùn)行結(jié)果:
10
*/
案例5
線程 t1 打斷 t2(interrupt)前對(duì)變量的寫,對(duì)于其他線程得知 t2 被打斷后對(duì)變量的讀可見(通過(guò) 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);
}
/*
運(yùn)行結(jié)果:
10
*/
案例6
對(duì)變量默認(rèn)值(0,false,null)的寫,對(duì)其它線程對(duì)該變量的讀可見
static int a;
public static void main(String[] args) {
new Thread(()->{
System.out.println(a);
}).start();
}
/*
運(yùn)行結(jié)果:
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 對(duì) t2 可見, 同時(shí) y=10 也對(duì) t2 可見
System.out.println(x);
},"t2").start();
/*
運(yùn)行結(jié)果:
20
*/以上就是java線程之Happens-before規(guī)則的詳細(xì)內(nèi)容,更多關(guān)于線程Happens-before規(guī)則的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
springboot多文件上傳實(shí)現(xiàn)使用postman測(cè)試多文件上傳接口
這篇文章主要介紹了springboot多文件上傳實(shí)現(xiàn)使用postman測(cè)試多文件上傳接口,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
java動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理示例分享
這篇文章主要介紹了java動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理示例,JDK1.3之后,Java提供了動(dòng)態(tài)代理的技術(shù),允許開發(fā)者在運(yùn)行期間創(chuàng)建接口的代理實(shí)例,下面我們使用示例學(xué)習(xí)一下2014-03-03
springboot webflux 過(guò)濾器(使用RouterFunction實(shí)現(xiàn))
這篇文章主要介紹了springboot webflux 過(guò)濾器(使用RouterFunction實(shí)現(xiàn)),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
Maven項(xiàng)目打包成war包部署到Tomcat的方法
這篇文章主要介紹了Maven項(xiàng)目打包成war包部署到Tomcat的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-06-06
聊聊@value注解和@ConfigurationProperties注解的使用
這篇文章主要介紹了@value注解和@ConfigurationProperties注解的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
java實(shí)現(xiàn)Flappy Bird游戲源代碼
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)Flappy Bird游戲源代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12
springboot用戶數(shù)據(jù)修改的詳細(xì)實(shí)現(xiàn)
用戶管理功能作為所有的系統(tǒng)是必不可少的一部分,下面這篇文章主要給大家介紹了關(guān)于springboot用戶數(shù)據(jù)修改的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04
mybatis if test條件判斷語(yǔ)句中的判斷問(wèn)題分析
這篇文章主要介紹了mybatis if test條件判斷語(yǔ)句中的判斷問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
Java中通過(guò)Class類獲取Class對(duì)象的方法詳解
這篇文章主要給大家介紹了關(guān)于Java中通過(guò)Class類獲取Class對(duì)象的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-08-08

