一、鎖種類
偏向鎖
因?yàn)榻?jīng)過(guò)HotSpot的作者大量的研究發(fā)現(xiàn)叨吮,大多數(shù)時(shí)候是不存在鎖競(jìng)爭(zhēng)的形纺,常常是一個(gè)線程多次獲得同一個(gè)鎖,因此如果每次都要競(jìng)爭(zhēng)鎖會(huì)增大很多沒(méi)有必要付出的代價(jià)危彩,為了降低獲取鎖的代價(jià)攒磨,才引入的偏向鎖。
輕量級(jí)鎖
輕量級(jí)鎖考慮的是競(jìng)爭(zhēng)鎖對(duì)象的線程不多汤徽,而且線程持有鎖的時(shí)間也不長(zhǎng)的情景娩缰。因?yàn)樽枞€程需要CPU從用戶態(tài)轉(zhuǎn)到內(nèi)核態(tài)抒抬,代價(jià)較大朦拖,如果剛剛阻塞不久這個(gè)鎖就被釋放了走净,那這個(gè)代價(jià)就有點(diǎn)得不償失了桦沉,因此這個(gè)時(shí)候就干脆不阻塞這個(gè)線程嘴秸,讓它自旋這等待鎖釋放劲弦。
自旋鎖
減少線程上下文切換置尔,提高執(zhí)行效率
重量級(jí)鎖
除擁有鎖的線程外阻塞所有競(jìng)爭(zhēng)線程
二妄讯、具體過(guò)程
線程A在進(jìn)入同步代碼塊前趋惨,先檢查MarkWord中的線程ID是否與當(dāng)前線程ID一致鸟顺,如果一致(還是線程A獲取鎖對(duì)象),則無(wú)需使用CAS來(lái)加鎖器虾、解鎖讯嫂。
如果不一致,再檢查是否為偏向鎖兆沙,如果不是欧芽,則自旋等待鎖釋放。
如果是葛圃,再檢查該線程是否存在(偏向鎖不會(huì)主動(dòng)釋放鎖)千扔,如果不在,則設(shè)置線程ID為線程A的ID库正,此時(shí)依然是偏向鎖曲楚。
如果還在,則暫停該線程褥符,同時(shí)將鎖標(biāo)志位設(shè)置為00即輕量級(jí)鎖(將MarkWord復(fù)制到該線程的棧幀中并將MarkWord設(shè)置為棧幀中鎖記錄)龙誊。線程A自旋等待鎖釋放。
如果自旋次數(shù)到了該線程還沒(méi)有釋放鎖喷楣,或者該線程還在執(zhí)行趟大,線程A還在自旋等待鹤树,這時(shí)又有一個(gè)線程B過(guò)來(lái)競(jìng)爭(zhēng)這個(gè)鎖對(duì)象,那么這個(gè)時(shí)候輕量級(jí)鎖就會(huì)膨脹為重量級(jí)鎖护昧。重量級(jí)鎖把除了擁有鎖的線程都阻塞魂迄,防止CPU空轉(zhuǎn)。
如果該線程釋放鎖惋耙,則會(huì)喚醒所有阻塞線程捣炬,重新競(jìng)爭(zhēng)鎖。