轉(zhuǎn)載: http://java.chinaitlab.com/line/779789_2.html
?
?
synchronized關(guān)鍵字有兩種用法。第一種就是在《使用Synchronized關(guān)鍵字同步類方法》一文中所介紹的直接用在方法的定義中。另外一種就是synchronized塊。我們不僅可以通過synchronized塊來同步一個(gè)對象變量。也可以使用synchronized塊來同步類中的靜態(tài)方法和非靜態(tài)方法。
??? synchronized塊的語法如下:
public
?
void
?method()
{ ??? …?… ???? synchronized (表達(dá)式) ????{ ????????…?… ????} } |
??? 一、非靜態(tài)類方法的同步
??? 從《使用Synchronized關(guān)鍵字同步類方法》一文中我們知道使用synchronized關(guān)鍵字來定義方法就會(huì)鎖定類中所有使用synchronzied關(guān)鍵字定義的靜態(tài)方法或非靜態(tài)方法,但這并不好理解。而如果使用synchronized塊來達(dá)到同樣的效果,就不難理解為什么會(huì)產(chǎn)生這種效果了。如果想使用synchronized塊來鎖定類中所有的同步非靜態(tài)方法,需要使用this做為synchronized塊的參數(shù)傳入synchronized塊國,代碼如下:
??? 通過synchronized塊同步非靜態(tài)方法
??
001
??
public
?
class
?SyncBlock
?? 002 ??{ ?? 003 ?????? public ? void ?method1() ?? 004 ??????{ ?? 005 ?????????? synchronized ( this )?? // ?相當(dāng)于對method1方法使用synchronized關(guān)鍵字 ?? 006 ??????????{ ?? 007 ??????????????…?… ?? 008 ??????????} ?? 009 ??????} ?? 010 ?????? public ? void ?method2() ?? 011 ??????{ ?? 012 ?????????? synchronized ( this )?? // ?相當(dāng)于對method2方法使用synchronized關(guān)鍵字 ?? 013 ??????????{ ?? 014 ??????????????…?… ?? 015 ??????????} ?? 016 ??????} ?? 017 ?????? public ? synchronized ? void ?method3()?? ?? 018 ??????{ ?? 019 ??????????…?… ?? 020 ??????} ?? 021 ??} |
??? 在上面的代碼中的method1和method2方法中使用了synchronized塊。而第017行的method3方法仍然使用synchronized關(guān)鍵字來定義方法。在使用同一個(gè)SyncBlock類實(shí)例時(shí),這三個(gè)方法只要有一個(gè)正在執(zhí)行,其他兩個(gè)方法就會(huì)因未獲得同步鎖而被阻塞。在使用synchronized塊時(shí)要想達(dá)到和synchronized關(guān)鍵字同樣的效果,必須將所有的代碼都寫在synchronized塊中,否則,將無法使當(dāng)前方法中的所有代碼和其他的方法同步。
??? 除了使用this做為synchronized塊的參數(shù)外,還可以使用SyncBlock.this作為synchronized塊的參數(shù)來達(dá)到同樣的效果。
??? 在內(nèi)類(InnerClass)的方法中使用synchronized塊來時(shí),this只表示內(nèi)類,和外類(OuterClass)沒有關(guān)系。但內(nèi)類的非靜態(tài)方法可以和外類的非靜態(tài)方法同步。如在內(nèi)類InnerClass中加一個(gè)method4方法,并使method4方法和SyncBlock的三個(gè)方法同步,代碼如下:
??? 使內(nèi)類的非靜態(tài)方法和外類的非靜態(tài)方法同步
public
?
class
?SyncBlock
{ ????…?… ??? class ?InnerClass ??? { ??????? public ? void ?method4() ??????? { ??????????? synchronized (SyncBlock. this ) ?????? ? ?? { ?????????? ? ?? …?…? ?????? ? ?? } ??????? } ??? } ??? …?… } |
??? 在上面SyncBlock類的新版本中,InnerClass類的method4方法和SyncBlock類的其他三個(gè)方法同步,因此,method1、method2、method3和method4四個(gè)方法在同一時(shí)間只能有一個(gè)方法執(zhí)行。
??? Synchronized塊不管是正常執(zhí)行完,還是因?yàn)槌绦虺鲥e(cuò)而異常退出synchronized塊,當(dāng)前的synchronized塊所持有的同步鎖都會(huì)自動(dòng)釋放。因此,在使用synchronized塊時(shí)不必?fù)?dān)心同步鎖的釋放問題。
?
二、靜態(tài)類方法的同步
??? 由于在調(diào)用靜態(tài)方法時(shí),對象實(shí)例不一定被創(chuàng)建。因此,就不能使用this來同步靜態(tài)方法,而必須使用Class對象來同步靜態(tài)方法。代碼如下:
??? 通過synchronized塊同步靜態(tài)方法
???
public
?
class
?StaticSyncBlock
???{ ??????? public ? static ? void ?method1() ???????{ ??????????? synchronized (StaticSyncBlock. class )?? ???????????{ ???????????????…?… ???????????} ???????} ??????? public ? static ? synchronized ? void ?method2()?? ???????{ ???????????…?… ???????} ???} |
??? 在同步靜態(tài)方法時(shí)可以使用類的靜態(tài)字段class來得到Class對象。在上例中method1和method2方法同時(shí)只能有一個(gè)方法執(zhí)行。除了使用class字段得到Class對象外,還可以使用實(shí)例的getClass方法來得到Class對象。上例中的代碼可以修改如下:
??? 使用getClass方法得到Class對象
public
?
class
?StaticSyncBlock
{ ??? public ? static ?StaticSyncBlock?instance;? ??? public ?StaticSyncBlock() ??? { ??????? instance? = ? this ; ??? } ??? public ? static ? void ?method1() ??? { ??????? synchronized (instance.getClass()) ?????? { ??????????? ![]() ![]() ?????? } ??? } ??? ![]() ![]() } |
??? 在上面代碼中通過一個(gè)public的靜態(tài)instance得到一個(gè)StaticSyncBlock類的實(shí)例,并通過這個(gè)實(shí)例的getClass方法得到了Class對象(一個(gè)類的所有實(shí)例通過getClass方法得到的都是同一個(gè)Class對象,因此,調(diào)用任何一個(gè)實(shí)例的getClass方法都可以)。我們還可以通過Class對象使不同類的靜態(tài)方法同步,如Test類的靜態(tài)方法method和StaticSyncBlock類的兩個(gè)靜態(tài)方法同步,代碼如下:
??? Test類的method方法和StaticSyncBlock類的method1、method2方法同步
???
public
?
class
?Test
???{ ??????? public ? static ? void ?method() ???????{ ??????????? synchronized (StaticSyncBlock. class ) ???????????{ ??????????????? ![]() ![]() ???????????} ???????} ???} |
??? 注意:在使用synchronized塊同步類方法時(shí),非靜態(tài)方法可以使用this來同步,而靜態(tài)方法必須使用Class對象來同步。它們互不影響。當(dāng)然,也可以在非靜態(tài)方法中使用Class對象來同步靜態(tài)方法。但在靜態(tài)方法中不能使用this來同步非靜態(tài)方法。這一點(diǎn)在使用synchronized塊同步類方法時(shí)應(yīng)注意。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
