一、synchronized鎖定的目標(biāo)

如圖所示,非常明了了,歸根結(jié)底,synchronized鎖定的既不是代碼塊、也不是一個(gè)方法,而是一個(gè)對象:方法鎖鎖定的是當(dāng)前類的實(shí)例對象、靜態(tài)方法鎖鎖定的是當(dāng)前類的類對象、對象鎖鎖定的是目標(biāo)對象、類鎖鎖定的是對應(yīng)類的類對象。
為什么是這樣呢?因?yàn)閟ynchronized鎖的信息保存在目標(biāo)對象的對象頭的markword中,當(dāng)運(yùn)行到synchronized代碼的時(shí)候,JVM會(huì)讀取被鎖定對象的頭部信息,以確定當(dāng)前是否存在線程競爭。這時(shí)會(huì)觸發(fā)synchronized的鎖升級(jí)過程。
二、鎖分類
公平鎖/非公平鎖
公平鎖指的是線程按照申請順序獲取鎖,非公平鎖指線程不按照申請順序獲取鎖。
synchronized是非公平鎖。
可重入鎖/不可重入鎖
可重入鎖指的是線程獲取鎖之后,在內(nèi)部再次獲取同一個(gè)鎖時(shí),不會(huì)發(fā)生死鎖;不可重入鎖反之。
synchronized是可重入鎖。
樂觀鎖/悲觀鎖
樂觀鎖的思想是認(rèn)為操作過程中數(shù)據(jù)不會(huì)被其他線程修改,只有在修改數(shù)據(jù)的時(shí)候才會(huì)進(jìn)行判斷,這點(diǎn)一般通過CAS實(shí)現(xiàn)。
悲觀鎖則總是假設(shè)最壞情況發(fā)生,所以每次操作的時(shí)候就會(huì)阻止其他線程執(zhí)行相同操作,直到本線程執(zhí)行完畢為止。
樂觀鎖、悲觀鎖并不是真正指的一種鎖,而是一種思想。樂觀鎖常用于多讀少寫的場景,而悲觀鎖相反。
下面代碼是樂觀鎖和悲觀鎖的示例,其中i++模擬了事務(wù)的執(zhí)行。
// 樂觀鎖
public void useOptimisticLock() {
while (true) {
final int oldI = i;
Transaction transaction = createTransaction(oldI);
// 模擬執(zhí)行transaction
if (unsafe.compareAndSwapInt(this, I_OFFSET, oldI, oldI + 1)) {
return;
}
}
}
// 悲觀鎖
public void usePessimisticLock() {
synchronized (LOCK) {
Transaction transaction = createTransaction(i);
// 模擬執(zhí)行transaction
i++;
}
}
參考資料
Oracle官方文檔:synchronized
徹底理解synchronized
樂觀鎖 vs. 悲觀鎖
視頻教程:馬士兵Synchronized