悲觀鎖和樂觀鎖
我們都知道膘融,cpu是時分復(fù)用的腊凶,也就是把cpu的時間片划咐,分配給不同的thread/process輪流執(zhí)行,時間片與時間片之間钧萍,需要進(jìn)行cpu切換褐缠,也就是會發(fā)生進(jìn)程的切換。切換涉及到清空寄存器风瘦,緩存數(shù)據(jù)队魏。然后重新加載新的thread所需數(shù)據(jù)。當(dāng)一個線程被掛起時,加入到阻塞隊列胡桨,在一定的時間或條件下官帘,在通過notify(),notifyAll()喚醒回來昧谊。
在某個資源不可用的時候刽虹,就將cpu讓出,把當(dāng)前等待線程切換為阻塞狀態(tài)呢诬。等到資源(比如一個共享數(shù)據(jù))可用了涌哲,那么就將線程喚醒,讓他進(jìn)入runnable狀態(tài)等待cpu調(diào)度尚镰。這就是典型的悲觀鎖的實現(xiàn)阀圾。
但是,由于在進(jìn)程掛起和恢復(fù)執(zhí)行過程中存在著很大的開銷钓猬。 當(dāng)一個線程正在等待鎖時稍刀,它不能做任何事,所以悲觀鎖有很大的缺點敞曹。舉個例子账月,如果一個線程需要某個資源,但是這個資源的占用時間很短澳迫,當(dāng)線程第一次搶占這個資源時局齿,可能這個資源被占用,如果此時掛起這個線程橄登,可能立刻就發(fā)現(xiàn)資源可用抓歼,然后又需要花費很長的時間重新?lián)屨兼i,時間代價就會非常的高拢锹。
所以就有了樂觀鎖的概念谣妻,他的==核心思路就是,每次不加鎖而是假設(shè)沒有沖突而去完成某項操作卒稳,如果因為沖突失敗就重試蹋半,直到成功為止。== 在上面的例子中充坑,某個線程可以不讓出cpu,而是一直while循環(huán)减江,如果失敗就重試,直到成功為止捻爷。所以辈灼,當(dāng)數(shù)據(jù)爭用不嚴(yán)重時,樂觀鎖效果更好也榄。 比如CAS就是一種樂觀鎖思想的應(yīng)用巡莹。
Java中CAS的實現(xiàn)
CAS就是Compare and Swap的意思,比較并操作。很多的cpu直接支持CAS指令榕莺。CAS是項樂觀鎖技術(shù)俐芯,當(dāng)多個線程嘗試使用CAS同時更新同一個變量時,只有其中一個線程能更新變量的值钉鸯,而其它線程都失敗吧史, 失敗的線程并不會被掛起,而是被告知這次競爭中失敗唠雕,并可以再次嘗試贸营。
CAS有3個操作數(shù),內(nèi)存值V岩睁,舊的預(yù)期值A(chǔ)钞脂,要修改的新值B。當(dāng)且僅當(dāng)預(yù)期值A(chǔ)和內(nèi)存值V相同時捕儒,將內(nèi)存值V修改為B冰啃,否則什么都不做。