- 線程安全
- 什么是synchronized關(guān)鍵字?
- synchronized實(shí)現(xiàn)方式
- 1.修飾實(shí)例方法
- 2.修飾靜態(tài)方法
- 3.修飾代碼塊
- synchronized關(guān)鍵字底層原理
- synchronized修飾實(shí)例方法
- monitor鎖是什么?
- Java對(duì)象內(nèi)存布局
- synchronized修飾代碼塊
- 鎖優(yōu)化
- 自旋鎖
- 鎖粗化
- 鎖消除
- 鎖膨脹
- synchronized關(guān)鍵字實(shí)現(xiàn)單例模式
- synchronized 和 volatile 的區(qū)別?
- 尾語(yǔ)
- 參考資料:
前言
今天我們來(lái)聊聊synchronized關(guān)鍵字,其可以同時(shí)保證三者,實(shí)現(xiàn)線程安全。
線程安全
在介紹synchronized關(guān)鍵字
之前,我們得強(qiáng)調(diào)一下什么是線程安全,所謂線程安全:
當(dāng)多個(gè)線程同時(shí)訪問(wèn)一個(gè)對(duì)象時(shí), 如果不用考慮這些線程在運(yùn)行時(shí)環(huán)境下的調(diào)度和交替執(zhí)行, 也不需要進(jìn)行額外的同步, 或者在調(diào)用方進(jìn)行任何其他的協(xié)調(diào)操作, 調(diào)用這個(gè)對(duì)象的行為都可以獲得正確的結(jié)果, 那就稱這個(gè)對(duì)象是線程安全的 。
什么是synchronized關(guān)鍵字?
在 Java 早期版本中,synchronized 屬于 重量級(jí)鎖 ,效率低下;不過(guò)在 Java 6 之后,Java 官方對(duì)從 JVM 層面對(duì) synchronized 較大優(yōu)化,所以現(xiàn)在的 synchronized 鎖效率也優(yōu)化得非常不錯(cuò)。目前不論是各種開(kāi)源框架還是 JDK 源碼都大量使用了 synchronized 關(guān)鍵字
synchronized實(shí)現(xiàn)方式
synchronized
的使用其實(shí)比較簡(jiǎn)單,可以用它來(lái)修飾實(shí)例方法和靜態(tài)方法,也可以用來(lái)修飾代碼塊。我們需要注意的是synchronized
是一個(gè)對(duì)象鎖,也就是它鎖的是一個(gè)對(duì)象。我們無(wú)論使用哪一種方法,synchronized
都需要有一個(gè)鎖對(duì)象
- 修飾實(shí)例方法
- 修飾靜態(tài)方法
- 修飾代碼塊
1.修飾實(shí)例方法
synchronized修飾實(shí)例方法, 在方法上加上synchronized關(guān)鍵字即可。
public class SynchronizedTest1 {
public synchronized void test() {
System.out.println("synchronized 修飾 方法");
}
}
此時(shí),synchronized加鎖的對(duì)象就是這個(gè)方法所在實(shí)例的本身,作用于當(dāng)前實(shí)例加鎖,進(jìn)入同步代碼前要獲得 當(dāng)前實(shí)例的鎖 。
補(bǔ)充一個(gè)常見(jiàn)的面試題:構(gòu)造方法可以用synchronized關(guān)鍵字修飾嗎?
不能,也不需要,因?yàn)闃?gòu)造方法本身就是線程安全的
2.修飾靜態(tài)方法
synchronized修飾靜態(tài)方法的使用與實(shí)例方法并無(wú)差別,在靜態(tài)方法上加上synchronized關(guān)鍵字即可
public static synchronized void test(){
i++;
}
由于靜態(tài)方法不屬于任何一個(gè)實(shí)例對(duì)象,歸整個(gè)類(lèi)所有,不依賴于類(lèi)的特定實(shí)例,被類(lèi)的所有實(shí)例共享。給靜態(tài)方法加synchronized
鎖,會(huì)作用于類(lèi)的所有對(duì)象實(shí)例 ,進(jìn)入同步代碼前要獲得 當(dāng)前靜態(tài)方法所在類(lèi)的Class對(duì)象的鎖 。
有一點(diǎn)我們需要知道:如果一個(gè)線程 A 調(diào)用一個(gè)實(shí)例對(duì)象的非靜態(tài) synchronized 方法,而線程 B 需要調(diào)用這個(gè)實(shí)例對(duì)象所屬類(lèi)的靜態(tài) synchronized 方法,是允許的,不會(huì)發(fā)生互斥現(xiàn)象, 因?yàn)樵L問(wèn)靜態(tài) synchronized 方法占用的鎖是當(dāng)前類(lèi)的鎖,而訪問(wèn)非靜態(tài) synchronized 方法占用的鎖是當(dāng)前實(shí)例對(duì)象鎖 。
3.修飾代碼塊
synchronized修飾代碼塊需要傳入一個(gè)對(duì)象。
public class SynchronizedTest2 {
public void test() {
synchronized (this) {
System.out.println("synchronized 修飾 代碼塊");
}
}
}
此時(shí)synchronized加鎖對(duì)象即為傳入的這個(gè)對(duì)象實(shí)例,指定加鎖對(duì)象,進(jìn)入同步代碼庫(kù)前要獲得給定對(duì)象的鎖 需要注意的是這里的**this **:
- synchronized(object) ,表示進(jìn)入同步代碼庫(kù)前要獲得 給定對(duì)象的鎖
- synchronized(類(lèi).class) ,表示進(jìn)入同步代碼前要獲得 給定 Class 的鎖
- 最好不要使用 synchronized(String a) ,因?yàn)樵?JVM 中,字符串常量池具有緩存功能, 如果我們多次加鎖,會(huì)加鎖在同一個(gè)對(duì)象上
-
JAVA
+關(guān)注
關(guān)注
19文章
2973瀏覽量
104913 -
代碼
+關(guān)注
關(guān)注
30文章
4810瀏覽量
68829 -
線程安全
+關(guān)注
關(guān)注
0文章
13瀏覽量
2469
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論