スレッドの同期(ブロック)
スレッドの同期を取るもう一つの手段として shnchronizedブロック があります。
以下のように記述することにより()内で指定したオブジェクトのモニタを獲得することができます。

synchronized(obj){
    //ステートメント
    
}
{}内ではobjのモニタを獲得していますが、{}を抜けるとモニタを開放します。
以下にsynchronizedブロックを使用した例を示します。
以下のクラスのaddIメソッドを実行すると、まずobj1のモニタを獲得し、変数iをインクリメントして1秒待機しています。
待機後、addIメソッドを実行したスレッド名とiを表示して終了しています。

public class MySynchronized {
    Object obj1;
    int i;
    MySynchronized(){
        obj1 = new Object();
        i    = 0;
    }
    
    public void addI(String name){
        synchronized (obj1) {
            i = i + 1;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
            System.out.println(name + ":" + getI());
        }
    }
    
    public int getI(){
        return i;
    }
}
以下は、上記クラスをインスタンス化し、二つのスレッドでaddIを呼んでいます。
addIメソッド内でsynchronizedしているため、addIは交互にモニタを獲得し、同期が取れているのがわかります。

public class TEST {
    static MySynchronized ms = new MySynchronized();
    
    public static void main(String[] args){
        Thread thread1 = new Thread(){

            public void run(){
                for (int i=0;i<5;i++){
                    ms.addI("thread-1.add");
                }
            }
        };
        
        Thread thread2 = new Thread(){
            public void run(){
                for (int i=0;i<5;i++){
                    ms.addI("thread-2.add");
                }
            }
        };
        
        thread1.start();
        thread2.start();

    }
}

上記、Javaアプリケーションを実行すると結果は以下のようになります。
最初にthread-1がaddIメソッドを実行し、その中で1秒待機しているため、thread-2がモニタ獲得待ち状態になり、thread-1がモニタ解放後thread-2がaddIを実行しているのがわかります。
そのモニタ獲得と開放を繰り返しthread-1とthread-2の間で繰り返しています。

thread-1.add:1
thread-2.add:2
thread-1.add:3
thread-2.add:4
thread-1.add:5
thread-2.add:6
thread-1.add:7
thread-2.add:8
thread-1.add:9
thread-2.add:10

Back to top

Information