线程_内部锁和同步
為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??
內(nèi)部鎖和同步
同步是使用被叫做內(nèi)部鎖或者監(jiān)控鎖(intrinsiclock or monitor lock.)的內(nèi)部實體來實現(xiàn)的。(API文檔里面經(jīng)常簡稱做monitor)內(nèi)部鎖在同步的兩個方面都扮演了重要的角色:強制對一個對象狀態(tài)的獨占性訪問,建立“happens-before”關(guān)系,happens-before關(guān)系對可見性很重要。
每個對象都有一個與它相關(guān)的內(nèi)部鎖。通常,一個線程需要對一個對象的域進行獨占性訪問或者一致性訪問的時候,這個線程就需要在訪問前去獲得這個對象 的內(nèi)部鎖,然后在做完相關(guān)操作后釋放鎖。可以說一個線程在它請求和釋放鎖的這段時間擁有這個內(nèi)部鎖。只要一個線程擁有一個對象的內(nèi)部鎖,其他的對象就不能 再擁有它,其他對象在嘗試獲得時會被阻塞。
當(dāng)一個線程釋放一個內(nèi)部鎖的時候,這個釋放行為和后續(xù)對這個鎖的獲得行為就建立了“happens-before”關(guān)系。
同步方法中的鎖
當(dāng)一個線程調(diào)用一個同步方法的時候,它會自動取請求這個方法的對象所擁有的鎖,方法return的時候自動釋放。即便方法是因為一個未捕獲異常而返回的鎖依然會被釋放。
你或許會疑惑一個靜態(tài)的同步方法被調(diào)用會發(fā)生什么,因為static的方法是跟類相關(guān)的而不是跟實例相關(guān)。這種情況下,線程會去嘗試獲得與這個類相關(guān)的Class對象的內(nèi)部鎖。所以對類的靜態(tài)域的訪問和對實例的訪問是受控于不同的鎖。
同步塊
另一種創(chuàng)建同步代碼的方式是使用同步塊,與使用同步方法不同,使用同步塊時必須指定提供內(nèi)部鎖的對象。
public void addName(String name){
??? synchronized(this) {
??????? lastName = name;
??????? nameCount++;
??? }
??? nameList.add(name);
}
?
在這個例子中,addName方法需要去同步對lastName和nameCount的改變,但是也需要防止對其他對象的方法的同步調(diào)用。(對其他 對象的方法在同步塊中調(diào)用可能產(chǎn)生生命性問題。)如果不用同步塊的話,那就需要為只為了調(diào)用nameList.add(name)而創(chuàng)建一個單獨的,非同 步的方法。
同步塊對于提高非常精細(xì)的同步的并發(fā)性也是很有用的。假設(shè),類MsLunch有兩個字段,c1和c2,他們不會被同時使用。對于兩個字段的所有單獨 的更改操作都需要被同步,但是沒有理由組織對c1的更改操作和對c2的更改操作交錯執(zhí)行,這樣反而因為多余的阻塞而降低了并發(fā)。我們可以創(chuàng)建兩個單獨的對 象來提供不同的鎖:
public?class?MsLunch?{ ????private?long?c1?=?0; ????private?long?c2?=?0; ????private?Object?lock1?=?new?Object(); ????private?Object?lock2?=?new?Object(); ?????public?void?inc1()?{ ????????synchronized(lock1)?{ ????????????c1++; ????????} ????} ?
????public?void?inc2()?{ ????????synchronized(lock2)?{ ????????????c2++; ????????} ????} }
?
使用這種方式需要特別小心,你必須絕對的肯定相關(guān)的方法可以被交錯的調(diào)用。
折返同步
回想前面所說的一個線程不能獲得另外一個線程已經(jīng)擁有的鎖。但是一個線程可以獲得它自己已經(jīng)擁有的鎖。允許一個線程不只一次的獲得它自己已經(jīng)擁有的 鎖,這樣能夠保證折返同步。這描述了這樣一個場景,一個同步的代碼,直接或者間接的調(diào)用了另外一個同步方法,而這兩個同步方法擁有同一個鎖。如果沒有折返 同步的話,同步代碼需要做更多額外的工作來保證它不被自己的鎖阻塞。
轉(zhuǎn)載于:https://my.oschina.net/ZGang/blog/375287
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
- 上一篇: 网络中间设备路在何方
- 下一篇: UncaughtExceptionHan