-
非靜態同步方法
如果使用synchronized來鎖定類中所有的同步非靜態方法,只需要使用this作為synchronized塊的參數傳入synchronized塊中
1 public class Test 2 { 3 public void method1() 4 { 5 synchronized(this) //或者使用Test.this當參數
6 { 7 } 8 } 9
10 public synchronized void method2() 11 { 12 } 13 }
在上面的代碼中的method1使用了synchronized塊,method2方法是用了synchronized關鍵字來定義方法,如果使用同一個Test實例時,這兩個方法只要有一個在執行,其他的方法都會因未獲得同步鎖而被堵塞。除了使用this作為synchronized塊的參數,也可以使用Test.this作為synchronized塊的參數來達到同樣的效果。
在內類中使用synchronized塊中,this只表示內類,和外類(OuterClass)沒有關系。但是內類中的非靜態方法和外類的非靜態方法也可以同步。如果在內類中加個方法method3也可以使和Test里面的2個方法同步。
1 public class Test 2 { 3 class InnerClass 4 { 5 public void method3() 6 { 7 synchronized(Test.this){ 8
9 } 10 } 11 } 12 }
InnerClass的method3方法與Test的method1和method2方法在同一時間內只能有一個方法執行。
synchronized塊不管是正確執行完,還是因為程序出錯因異常退出synchronized塊,當前的synchronized塊所持有的同步鎖都會自動釋放,因此在使用synchronized塊不必擔心同步鎖的問題。
-
靜態同步方法
在調用靜態方法時,對象實例不一定被創建,因此,就不能使用this來同步靜態方法,而必須使用Class對象來同步靜態方法。
-
方法一:使用類名.class作為參數傳入synchronized塊
1 public class Test{ 2 pubic static void method1(){ 3 synchronized(Test.class){} 4 } 5 public static synchronized void method2(){} 6 } -
方法二:通過實例的getClass()方法獲取class對象
1 public class Test{ 2 public static void method1(){ 3 Test test = new Test(); 4 synchronized(test.getclass()){} 5 } 6 public static synchronized void method2(){} 7 }
注意一個類的所有實例通過getClass方法得到的都是同一個Class對象。我們也可以通過class使不同類的靜態方法同步。
1 //Test類中的方法和Test1類中方法同步。 2 public class Test1{ 3 public static void method1(){ 4 synchronized(Test.class){ 5 } 6 } 7 }
總結
靜態方法屬於類,同步靜態方法的鎖是加在類上;普通方法屬於對象,同步非靜態方法的鎖是加在那個對象上。
在使用synchronized塊來同步方法時,
非靜態方法:用this當做參數;
靜態方法:1、用類名.class當參數 2、通過實例的getClass()方法當參數。
參考網站:
http://blog.csdn.net/lonely_fireworks/article/details/7279218
