Java線程安全與鎖優(yōu)化

一、Java語言中的線程安全
? ? ?Java語言中各種操作共享數(shù)據(jù)分為:不可變、絕對線程安全、相對線程安全、線程兼容和線程對立。

不可變:不可變的對象一定是線程安全的?;緮?shù)據(jù)類型,在定義時(shí)使用final修飾它就可以保證不可變,對象類型,把對象中帶狀態(tài)的變量都聲明為final,這樣構(gòu)造函數(shù)結(jié)束后,它就是不可變的。
絕對線程安全:不管運(yùn)行時(shí)環(huán)境如何,調(diào)用者都不需要任何額外的同步措施。Vector舉例,多線程并發(fā)時(shí),并不安全。
相對線程安全:保證這個(gè)對象,單獨(dú)操作是線程安全的,我們在調(diào)用的時(shí)候需要做額外的保障措施,Vector,比如HashTable,Collections的synchronizedCollection
線程兼容:對象本身不是線程安全的,可以在調(diào)用端通過使用同步手段保證對象在并發(fā)環(huán)境中可以安全的使用,比如Arraylist、HashMap。
線程對立:無論采用什么手段,都無法保證對象在多線程并發(fā)環(huán)境中保證線程安全。

二、線程安全的實(shí)現(xiàn)方法
?1、互斥同步:阻塞同步,通過關(guān)鍵字synchronized,會(huì)在同步塊前加monitorenter、monitorexit這兩個(gè)字節(jié)碼指令。執(zhí)行monitorenter指令時(shí),首先嘗試獲取對象的鎖,如果對象沒有被鎖定或者對象已被鎖定,把鎖的計(jì)數(shù)器加1,在執(zhí)行monitorexit指令時(shí),操作計(jì)數(shù)器減1,當(dāng)計(jì)數(shù)器為0時(shí),鎖就被釋放,如果獲取鎖失敗,那當(dāng)前線程就要阻塞等待,直到鎖對象被另外一個(gè)線程釋放為止。
?ReentrantLock:具備線程重入特性,有等待可中斷,可實(shí)現(xiàn)公平鎖,以及鎖可以綁定多個(gè)條件。
等待可中斷:是指當(dāng)持有鎖的線程長期不釋放鎖的時(shí)候,正在等待的線程可以放棄等待,去處理其他的事情。
公平鎖:是指多個(gè)線程在等待同一個(gè)鎖時(shí),必須按照申請鎖的時(shí)間先后順序依次來獲得鎖,非公平鎖:在鎖被釋放時(shí),任何一個(gè)等待的鎖都有機(jī)會(huì)獲得鎖。synchronized鎖是非公平鎖,ReentrantLock默認(rèn)是非公平鎖,可以帶boolean指,為公平鎖。
鎖可以綁定多個(gè)條件。
2、非阻塞同步

二、鎖優(yōu)化
? ? ? 鎖包括自旋鎖與自適應(yīng)鎖,鎖消除、鎖粗化,輕量級鎖、偏向鎖。
? ? ? 自旋鎖:并發(fā)時(shí),請求鎖,稍等一下,但不放棄處理器的執(zhí)行時(shí)間,看看持有鎖的線程是否會(huì)很快釋放鎖,如果鎖占用時(shí)間短,自旋等待的效果較好,否則,白白浪費(fèi)處理器的時(shí)間,自旋的次數(shù)默認(rèn)10次。
? ? ? 自適應(yīng)鎖:就是自適應(yīng)的自旋鎖,自旋的時(shí)間不固定了,根據(jù)歷史獲取鎖的情況,自動(dòng)決定是否要自旋等待,若果一個(gè)鎖很多次不能通過自旋獲得鎖,下次可能就直接掛起而不是自旋等待。
? ? ? 鎖消除:對一些代碼上要求同步,但是檢測到不可能存在共享數(shù)據(jù)競爭的鎖進(jìn)行消除。
? ? ? 鎖粗化:如果一系列連續(xù)的操作都對同一個(gè)對象反復(fù)枷鎖和解鎖,就會(huì)采用鎖粗化,將鎖的范圍擴(kuò)大。
? ? ?輕量級鎖:無競爭的情況下,使用CAS操作去消除同步使用的互斥量。
? ? ?偏向鎖:無競爭的情況下,把整個(gè)同步都消除掉,CAS操作也不做了。

??

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容