JavaにおけるSynchronizedの使用上の注意事項
1841 ワード
回転:http://www.blogjava.net/freeman1984/archive/2011/10/17/361403.html Java 1.5の前に、synchronizedは最もよく使われているjavaサポート合併手段であるべきです.じゃ、synchronizedはどうやってできますか?java 1.0からjavaの中の各オブジェクトは一つの内部錠です.一つの種類の方法がsynchronizedキーワードによって修飾されると、このオブジェクトのロックは全体の方法を保護します.例えば:
なお、静的系をsynchronizedとして宣言する方法も合法的である.例えば、Syncにstatic synchronized方法があるなら、この方法が呼び出された時、Sync.classという種類のオブジェクト自体はjvmにロックされます.
public synchronized void method(){
method body
}
に等しいpublic void method(){
this.intrinsicLock.lock();
try{
method body;
}finally(){
this.intrinsicLock.unlock();
}
}
上のコード例から、synchronizedの使用は比較的簡単であることが分かります.これは多くの初心者がJavaプログラミングに遭遇した時に落とし穴に落ちてしまい、synhronizedがすべてを解決できるなら、たとえ3721であろうと、合併の可能性があるところであれば、synchronizedのキーワードを加えるのは明らかに間違っています.javaオブジェクトでは、このjavaオブジェクトはこの一つの内部錠だけであり、そのうちの一つのsynchronized方法はこのロックを取得し、もう一つのsynchronizedメソッドの呼び出しはブロックされます.すなわちclass sync{
public synchronized void methodA(){};
public synchronized void methodB(){};
... ...
}
methodAとmethodBは最初から互いに反発しあっています.methodAとmethodBが入って待ち合うと、デッドロックが発生しやすくなります.もしこのような状況に遭遇したら、どうすればいいですか?一般的な方法は、方法の内部に意味のないオブジェクトを新規作成し、この無意味なオブジェクトに同期ロックをかけることです.public class Sync {
private int i;
public void plus(){
Object dummy = new Object();
synchronized(dummy){
i++;
}
}
public void minus(){
Object dummy = new Object();
synchronized(dummy){
i--;
}
}
}
なお、静的系をsynchronizedとして宣言する方法も合法的である.例えば、Syncにstatic synchronized方法があるなら、この方法が呼び出された時、Sync.classという種類のオブジェクト自体はjvmにロックされます.