優(yōu)質(zhì)文章,第一時(shí)間送達(dá)
76套java從入門(mén)到精通實(shí)戰(zhàn)課程分享
一、volitile的理解
Volatile稱(chēng)之為輕量級(jí)鎖,被volatile修飾的變量,在線(xiàn)程之間是可見(jiàn)的。
可見(jiàn)即一個(gè)線(xiàn)程修改了這個(gè)變量的值,在另外一個(gè)線(xiàn)程中能夠讀到這個(gè)修改后的值。
Synchronized除了線(xiàn)程之間互斥以外,還有一個(gè)非常大的作用就是保證可見(jiàn)性。
保證可見(jiàn)性的前提,多個(gè)線(xiàn)程拿到的是同一把鎖,否則是保證不了的。
二、多個(gè)線(xiàn)程獲取值案例(沒(méi)有使用同步的情況)
1、代碼
package com.xz.thread.t6;
/**
* @description: 保證可見(jiàn)性的前提:多個(gè)線(xiàn)程拿到的是同一把鎖,否則是保證不了的。
*
* @author: xz
*/
public class Demo {
private int a=1;
public int getA() {
return a;
}
public void setA(int a) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.a = a;
}
public static void main(String[] args) {
Demo d=new Demo();
//第一個(gè)線(xiàn)程
new Thread(new Runnable() {
@Override
public void run() {
d.setA(10);
}
}).start();
//第二個(gè)線(xiàn)程
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(d.getA());
}
}).start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println('最終的結(jié)果:'+d.getA());
}
}
2、輸出結(jié)果
3、結(jié)論
在沒(méi)有使用同步的情況下,同一個(gè)實(shí)例中多個(gè)線(xiàn)程獲取的值是不相同的。
三、多個(gè)線(xiàn)程獲取值案例(使用Volatile關(guān)鍵字的情況)
1、代碼
package com.xz.thread.t6;
/**
* @description: 保證可見(jiàn)性的前提:多個(gè)線(xiàn)程拿到的是同一把鎖,否則是保證不了的。
* @author: xz
*/
public class Demo2 {
public volatile int a = 1;
public static void main(String[] args) {
Demo2 d=new Demo2();
new Thread(new Runnable() {
@Override
public void run() {
d.a = 10;
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(d.a);
}
}).start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println('最終的結(jié)果:'+d.a);
}
}
2、輸出結(jié)果
3、結(jié)論
在使用Volatile關(guān)鍵字的情況下,同一個(gè)實(shí)例中多個(gè)線(xiàn)程獲取的值是相同的。
四、多個(gè)線(xiàn)程獲按順序執(zhí)行的案例
1、代碼
package com.xz.thread.t6;
/**
* @description:
* @author: xz
*/
public class Demo3 {
public volatile Boolean run =false;
public static void main(String[] args) {
Demo3 d3=new Demo3();
//第一個(gè)線(xiàn)程
new Thread(new Runnable() {
@Override
public void run() {
for(int i=0;i<10;i++){
System.out.println('第【'+i+'】次執(zhí)行');
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
d3.run =true;//第一個(gè)線(xiàn)程執(zhí)行完把run變量改成true
}
}).start();
//第二個(gè)線(xiàn)程
new Thread(new Runnable() {
@Override
public void run() {
while (!d3.run){
//當(dāng)run !=true 時(shí),不執(zhí)行
}
System.out.println('線(xiàn)程2執(zhí)行了===========');
}
}).start();
}
}
2、輸出結(jié)果
五、 Lock指令的理解
volatile可見(jiàn)性是通過(guò)匯編加上Lock前綴指令完成的。由此引出Lock指令的理解。
在多處理器的系統(tǒng)上
將當(dāng)前處理器緩存行的內(nèi)容寫(xiě)回到系統(tǒng)內(nèi)存;
這個(gè)寫(xiě)回到內(nèi)存的操作會(huì)使在其他CPU里緩存了該內(nèi)存地址的數(shù)據(jù)失效。
六、有Volatile為什么還使用synchronized
volatile關(guān)鍵字可以保證內(nèi)存可見(jiàn)性和有序性,但不能保證原子性;
也就是說(shuō)synchronized可以取代Volatile,但是Volatile不能取代synchronized;
七、synchronized可以取代Volatile,為什么還用Volatile
Volatile稱(chēng)之為輕量級(jí)鎖。
————————————————
版權(quán)聲明:本文為CSDN博主「小志的博客」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
聯(lián)系客服