java synchronized同期静的方法と同期非静的方法の異同

4322 ワード

java synchronized詳細
synchronizedキーワードには2つの用法があります。一つは方法の定義にのみ使用されるもので、もう一つはsynchronizedブロックです。私たちはsynchronizedを使って一つのオブジェクト変数を同期させるだけでなく、synchronizdlを通してクラスの静的方法と非静的方法を同期させることもできます。
synchronizedブロックの文法は以下の通りです。

public void method() 
{ 
  synchronized(   ) 
   { 
   } 
 
} 


public void method() 
{ 
  synchronized(   ) 
   { 
   } 
 
} 
第一の方法:非静的方法の同期
Java関連の文法から、synchronizedキーワードを使って定義する方法がロックされます。synchroniezdキーワードを使って定義される静的な方法と非静的な方法が分かりますが、これはちょっと分かりにくいです。synchronizedを使用してクラス内のすべての同期非静的方法をロックする場合、synchronizedブロックのパラメータとしてthisを使用してsynchronizedブロックに入る必要があります。コードは以下の通りです。
  synchronizedブロックによる非静的方法の同期
上のコードの中のmethod 1は、synchronizedブロックを使用しています。method 2方法は、synchronizedキーワードを用いて方法を定義しています。同じTestインスタンスを使用すると、この2つの方法が実行されている限り、他の方法は同期ロックが得られないので、詰まってしまいます。thisをsynchronizedブロックのパラメータとして使用する以外に、Test.thisをsynchronizedブロックのパラメータとして使用しても同様の効果を達成することができます。

public class Test 
{ 
 public void method1() 
 { 
  synchronized(this) 
   { 
 
   } 
 } 
 
 public synchronized void method2() 
 { 
 
 } 
} 

public class Test 
{ 
 public void method1() 
 { 
  synchronized(this) 
   { 
 
   } 
 } 
 
 public synchronized void method2() 
 { 
 
 } 
} 
 内のクラスでは、synchronizedブロックを使用していますが、thisは内のクラスだけを表しています。外のクラスとは関係ありません。しかし内部クラスにおける非静的方法と外部クラスの非静的方法も同期できる。中にメソッドを追加すれば、Test内の2つの方法と同期することもできます。コードは以下の通りです。

public class Test 
{ 
 class InnerClass 
 { 
  public void method3() 
   { 
    synchronized(Test.this){ 
 
    } 
   } 
  } 
} 

public class Test 
{ 
 class InnerClass 
 { 
  public void method3() 
   { 
    synchronized(Test.this){ 
 
    } 
   } 
  } 
} 
上のInneraclassのmethod 3方法はTestのmethod 1とmethod 2方法と同じ時間に一つの方法でしか実行できません。
synchronizedブロックは正しく実行されても、プログラムエラーでsynchronizedブロックを異常に終了しても、現在のsynchronizedブロックが持つ同期ロックは自動的に解除されますので、synchronizedブロックを使用する場合は同期ロックの問題を心配する必要はありません。
二、静的方法の同期
静的方法を呼び出した場合、オブジェクトインスタンスは必ずしも作成されるとは限らないので、静的方法を同期するためにthisを使用することはできず、Classオブジェクトを使用して静的方法を同期させなければならない。コードは以下の通りです

public class Test{ 
 
 pubic static void method1(){ 
  synchronized(Test.class){ 
  } 
 } 
 public static synchronized void method2(){ 
 
  } 
} 

public class Test{ 
 
 pubic static void method1(){ 
  synchronized(Test.class){ 
  } 
 } 
 public static synchronized void method2(){ 
 
  } 
} 
静的方法を同期する際にクラスの静的フィールドクラスを使用してクラスのオブジェクトを得ることができ、上記の例ではmethod 1とmethod 2の方法は一つの方法でしか実行されません。classフィールドを使用することでクラスのオブジェクトが得られるほか、インスタンスのget Class()方法でクラスのオブジェクトを取得することができます。コードは以下の通りです。

public class Test{ 
 public static Test test; 
 public Test(){ 
 test=this; 
 } 
 public static void method1(){ 
 synchronized(test.getClass()){ 
 } 
 } 
} 

public class Test{ 
 public static Test test; 
 public Test(){ 
 test=this; 
 } 
 public static void method1(){ 
 synchronized(test.getClass()){ 
 } 
 } 
} 
上記のコードでは、publicの静的オブジェクトを通してTestの一例を得て、この例のget Class方法によって、クラスのすべてのインスタンスがget Class方法によって得られたのは同じクラスのオブジェクトであることに注意してください。また、クラスを通して異なる静的方法を同期させることもできます。コードは以下の通りです。
Testクラスにおける方法とTest 1クラスにおける方法は同期する。

public class Test1{ 
 public static void method1(){ 
 synchronized(Test.class){ 
  } 
 } 
} 

public class Test1{ 
 public static void method1(){ 
 synchronized(Test.class){ 
  } 
 } 
} 
注意:synchronizedブロックを用いて方法を同期する場合、非静的方法はthisによって同期され、静的方法はクラスオブジェクトを用いて同期されなければならないが、非静的方法はまた、classを用いて静的方法を同期させることができる。しかし静的方法では,thisを用いて非静的方法を同期することはできない。この点はsynchronizedブロックを使っていますので、注意が必要です。
読んでくれてありがとうございます。みなさんのご協力をお願いします。ありがとうございます。