java多線程編程之應用Synchronized塊同步辦法。本站提示廣大學習愛好者:(java多線程編程之應用Synchronized塊同步辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是java多線程編程之應用Synchronized塊同步辦法正文
synchronized症結字有兩種用法。第一種就是在《應用Synchronized症結字同步類辦法》一文中所引見的直接用在辦法的界說中。別的一種就是synchronized塊。我們不只可以經由過程synchronized塊來同步一個對象變量。也能夠應用synchronized塊來同步類中的靜態辦法和非靜態辦法。
synchronized塊的語法以下:
public void method()
{
… …
synchronized(表達式)
{
… …
}
}
1、非靜態類辦法的同步
從《應用Synchronized症結字同步類辦法》一文中我們曉得應用synchronized症結字來界說辦法就會鎖定類中一切應用synchronzied症結字界說的靜態辦法或非靜態辦法,但這其實不好懂得。而假如應用synchronized塊來到達異樣的後果,就不難懂得為何會發生這類後果了。假如想應用synchronized塊來鎖定類中一切的同步非靜態辦法,須要應用this做為synchronized塊的參數傳入synchronized塊國,代碼以下:
經由過程synchronized塊同步非靜態辦法
public class SyncBlock
{
public void method1()
{
synchronized(this) // 相當於對method1辦法應用synchronized症結字
{
… …
}
}
public void method2()
{
synchronized(this) // 相當於對method2辦法應用synchronized症結字
{
… …
}
}
public synchronized void method3()
{
… …
}
}
在下面的代碼中的method1和method2辦法中應用了synchronized塊。而第017行的method3辦法依然應用synchronized症結字來界說辦法。在應用統一個SyncBlock類實例時,這三個辦法只需有一個正在履行,其他兩個辦法就會因未取得同步鎖而被壅塞。在應用synchronized塊時要想到達和synchronized症結字異樣的後果,必需將一切的代碼都寫在synchronized塊中,不然,將沒法使以後辦法中的一切代碼和其他的辦法同步。
除應用this做為synchronized塊的參數外,還可使用SyncBlock.this作為synchronized塊的參數來到達異樣的後果。
在內類(InnerClass)的辦法中應用synchronized塊來時,this只表現內類,和外類(OuterClass)沒有關系。但內類的非靜態辦法可以和外類的非靜態辦法同步。如在內類InnerClass中加一個method4辦法,並使method4辦法和SyncBlock的三個辦法同步,代碼以下:
使內類的非靜態辦法和外類的非靜態辦法同步
public class SyncBlock
{
… …
class InnerClass
{
public void method4()
{
synchronized(SyncBlock.this)
{
… …
}
}
}
… …
}
在下面SyncBlock類的新版本中,InnerClass類的method4辦法和SyncBlock類的其他三個辦法同步,是以,method1、method2、method3和method4四個辦法在統一時光只能有一個辦法履行。
Synchronized塊不論是正常履行完,照樣由於法式失足而異常加入synchronized塊,以後的synchronized塊所持有的同步鎖都邑主動釋放。是以,在應用synchronized塊時不用擔憂同步鎖的釋放成績。
2、靜態類辦法的同步
因為在挪用靜態辦法時,對象實例紛歧定被創立。是以,就不克不及應用this來同步靜態辦法,而必需應用Class對象來同步靜態辦法。代碼以下:
經由過程synchronized塊同步靜態辦法
public class StaticSyncBlock
{
public static void method1()
{
synchronized(StaticSyncBlock.class)
{
… …
}
}
public static synchronized void method2()
{
… …
}
}
在同步靜態辦法時可使用類的靜態字段class來獲得Class對象。在上例中method1和method2辦法同時只能有一個辦法履行。除應用class字段獲得Class對象外,還可使用實例的getClass辦法來獲得Class對象。上例中的代碼可以修正以下:
應用getClass辦法獲得Class對象
public class StaticSyncBlock
{
public static StaticSyncBlock instance;
public StaticSyncBlock()
{
instance = this;
}
public static void method1()
{
synchronized(instance.getClass())
{
}
}
}
在下面代碼中經由過程一個public的靜態instance獲得一個StaticSyncBlock類的實例,並經由過程這個實例的getClass辦法獲得了Class對象(一個類的一切實例經由過程getClass辦法獲得的都是統一個Class對象,是以,挪用任何一個實例的getClass辦法都可以)。我們還可以經由過程Class對象使分歧類的靜態辦法同步,如Test類的靜態辦法method和StaticSyncBlock類的兩個靜態辦法同步,代碼以下:
Test類的method辦法和StaticSyncBlock類的method1、method2辦法同步
public class Test
{
public static void method()
{
synchronized(StaticSyncBlock.class)
{
}
}
}
留意:在應用synchronized塊同步類辦法時,非靜態辦法可使用this來同步,而靜態辦法必需應用Class對象來同步。它們互不影響。固然,也能夠在非靜態辦法中應用Class對象來同步靜態辦法。但在靜態辦法中不克不及應用this來同步非靜態辦法。這一點在應用synchronized塊同步類辦法時應留意。