Java中的鎖是實(shí)現(xiàn)多線程同步的重要手段。鎖可以保證同一個(gè)時(shí)刻只有一個(gè)線程能夠訪問(wèn)共享資源,避免了競(jìng)態(tài)條件與數(shù)據(jù)沖突的問(wèn)題。但是,在高并發(fā)環(huán)境下,頻繁地使用鎖機(jī)制也會(huì)導(dǎo)致一些性能問(wèn)題出現(xiàn)。
在Java中,鎖的使用存在兩個(gè)概念:鎖膨脹(Lock Escalation)和鎖降級(jí)(Lock Demotion)。
鎖膨脹是指在某個(gè)線程訪問(wèn)共享資源時(shí),由于系統(tǒng)內(nèi)存不足或者競(jìng)爭(zhēng)壓力過(guò)大等原因,操作系統(tǒng)會(huì)將輕量級(jí)鎖升級(jí)為重量級(jí)鎖。重量級(jí)鎖占用系統(tǒng)資源更多,導(dǎo)致系統(tǒng)性能下降。因此,Java中的鎖膨脹是一種防范措施,目的是為了避免線程競(jìng)爭(zhēng)造成死鎖等問(wèn)題。
public class SynchronizedDemo {
public synchronized void syncMethod() {
// do something
}
}
上述代碼中,使用了synchronized關(guān)鍵字對(duì)方法進(jìn)行加鎖。但是,在實(shí)際使用過(guò)程中,如果并發(fā)訪問(wèn)情況較嚴(yán)重,鎖膨脹的問(wèn)題就會(huì)出現(xiàn)。這時(shí),可以嘗試使用CAS操作或者分段鎖等技術(shù)來(lái)實(shí)現(xiàn)同步,避免鎖的升級(jí)。
鎖降級(jí)是指在一個(gè)操作完成后,將一個(gè)線程持有的重量級(jí)鎖轉(zhuǎn)變?yōu)檩p量級(jí)鎖。這樣可以避免在后續(xù)的操作中,因?yàn)楦?jìng)爭(zhēng)壓力不再發(fā)生而浪費(fèi)系統(tǒng)資源。鎖降級(jí)可以通過(guò)手動(dòng)控制來(lái)實(shí)現(xiàn),也可以通過(guò)JVM自動(dòng)實(shí)現(xiàn)。
public class SynchronizedDemo {
public void syncMethod() {
synchronized(this) {
// do something
}
}
}
上述代碼中,將鎖的對(duì)象由方法改為了具體的對(duì)象,這樣就實(shí)現(xiàn)了鎖的局部化,避免了鎖膨脹問(wèn)題。同時(shí),這種方式也能夠方便地實(shí)現(xiàn)鎖降級(jí),只需要在需要降級(jí)時(shí)將鎖修改為輕量級(jí)鎖即可。