一闹丐、Java語言中的線程安全
? ? ?Java語言中各種操作共享數(shù)據(jù)分為:不可變阱高、絕對線程安全赚导、相對線程安全、線程兼容和線程對立赤惊。
不可變:不可變的對象一定是線程安全的吼旧。基本數(shù)據(jù)類型未舟,在定義時使用final修飾它就可以保證不可變圈暗,對象類型,把對象中帶狀態(tài)的變量都聲明為final,這樣構(gòu)造函數(shù)結(jié)束后处面,它就是不可變的厂置。
絕對線程安全:不管運行時環(huán)境如何,調(diào)用者都不需要任何額外的同步措施魂角。Vector舉例,多線程并發(fā)時智绸,并不安全野揪。
相對線程安全:保證這個對象访忿,單獨操作是線程安全的,我們在調(diào)用的時候需要做額外的保障措施斯稳,Vector,比如HashTable,Collections的synchronizedCollection
線程兼容:對象本身不是線程安全的粱甫,可以在調(diào)用端通過使用同步手段保證對象在并發(fā)環(huán)境中可以安全的使用硝皂,比如Arraylist、HashMap。
線程對立:無論采用什么手段螃征,都無法保證對象在多線程并發(fā)環(huán)境中保證線程安全。
二挚躯、線程安全的實現(xiàn)方法
?1忍捡、互斥同步:阻塞同步,通過關(guān)鍵字synchronized,會在同步塊前加monitorenter竖幔、monitorexit這兩個字節(jié)碼指令板乙。執(zhí)行monitorenter指令時,首先嘗試獲取對象的鎖拳氢,如果對象沒有被鎖定或者對象已被鎖定募逞,把鎖的計數(shù)器加1,在執(zhí)行monitorexit指令時馋评,操作計數(shù)器減1放接,當計數(shù)器為0時,鎖就被釋放留特,如果獲取鎖失敗纠脾,那當前線程就要阻塞等待,直到鎖對象被另外一個線程釋放為止磕秤。
?ReentrantLock:具備線程重入特性乳乌,有等待可中斷,可實現(xiàn)公平鎖市咆,以及鎖可以綁定多個條件汉操。
等待可中斷:是指當持有鎖的線程長期不釋放鎖的時候,正在等待的線程可以放棄等待蒙兰,去處理其他的事情磷瘤。
公平鎖:是指多個線程在等待同一個鎖時,必須按照申請鎖的時間先后順序依次來獲得鎖搜变,非公平鎖:在鎖被釋放時采缚,任何一個等待的鎖都有機會獲得鎖。synchronized鎖是非公平鎖挠他,ReentrantLock默認是非公平鎖扳抽,可以帶boolean指,為公平鎖。
鎖可以綁定多個條件贸呢。
2镰烧、非阻塞同步
二、鎖優(yōu)化
? ? ? 鎖包括自旋鎖與自適應(yīng)鎖楞陷,鎖消除怔鳖、鎖粗化,輕量級鎖固蛾、偏向鎖结执。
? ? ? 自旋鎖:并發(fā)時,請求鎖艾凯,稍等一下献幔,但不放棄處理器的執(zhí)行時間,看看持有鎖的線程是否會很快釋放鎖览芳,如果鎖占用時間短斜姥,自旋等待的效果較好,否則沧竟,白白浪費處理器的時間铸敏,自旋的次數(shù)默認10次。
? ? ? 自適應(yīng)鎖:就是自適應(yīng)的自旋鎖悟泵,自旋的時間不固定了杈笔,根據(jù)歷史獲取鎖的情況,自動決定是否要自旋等待糕非,若果一個鎖很多次不能通過自旋獲得鎖蒙具,下次可能就直接掛起而不是自旋等待。
? ? ? 鎖消除:對一些代碼上要求同步朽肥,但是檢測到不可能存在共享數(shù)據(jù)競爭的鎖進行消除禁筏。
? ? ? 鎖粗化:如果一系列連續(xù)的操作都對同一個對象反復(fù)枷鎖和解鎖,就會采用鎖粗化衡招,將鎖的范圍擴大篱昔。
? ? ?輕量級鎖:無競爭的情況下,使用CAS操作去消除同步使用的互斥量始腾。
? ? ?偏向鎖:無競爭的情況下州刽,把整個同步都消除掉,CAS操作也不做了浪箭。
??