staticメソッドのSynchronizedについて 2019/5

以下のSyncTest2クラス内のssynchronizedであるone, two2つのメソッドは、インスタンス単位で同期される。
インスタンス間は同期対象ではない。
public class SyncTest2 {

    synchronized void one() {
        for (int i = 1; i <= 100; i++) 
            System.out.print("1");
        System.out.println();
    }

    synchronized void two() {
        for (int i = 1; i <= 100; i++) 
            System.out.print("2");
        System.out.println();
    }


    public static void main(String[] args) {

        SyncTest2 obj1 = new SyncTest2();
        SyncTest2 obj2 = new SyncTest2();
            
        ExecuteOne1 exeOne1 = new ExecuteOne1(obj1);
        ExecuteOne2 exeOne2 = new ExecuteOne2(obj1);
        
        ExecuteTwo1 exeTwo1 = new ExecuteTwo1(obj2);
        ExecuteTwo2 exeTwo2 = new ExecuteTwo2(obj2);
        
        exeOne1.start(); exeOne2.start();
        
        exeTwo1.start(); exeTwo2.start();
        
        try {
            exeOne1.join(); exeOne2.join();
            exeTwo1.join(); exeTwo2.join();
        }
        catch (InterruptedException ie) {
            ie.printStackTrace();
        }
    }
}

class ExecuteOne1 extends Thread {

    SyncTest2 obj;
    ExecuteOne1(SyncTest2 obj) {
        this.obj = obj;
    }

    public void run() {
        for (int i = 0; i < 100; i++)
            obj.one();
    }
}

class ExecuteOne2 extends Thread {

    SyncTest2 obj;
    ExecuteOne2(SyncTest2 obj) {
        this.obj = obj;
    }

    public void run() {
        for (int i = 0; i < 100; i++)
            obj.two();
    }
}

class ExecuteTwo1 extends Thread {

    SyncTest2 obj;
    ExecuteTwo1(SyncTest2 obj) {
        this.obj = obj;
    }

    public void run() {
        for (int i = 0; i < 100; i++)
            obj.one();
    }
}

class ExecuteTwo2 extends Thread {

    SyncTest2 obj;
    ExecuteTwo2(SyncTest2 obj) {
        this.obj = obj;
    }

    public void run() {
        for (int i = 0; i < 100; i++)
            obj.two();
    }
}

上記のsynchnorizedメソッドは、以下のように書くのと同じ同期の効果が得られる。
public class SyncTest2 {

    void one() {
        synchronized(this) {
            for (int i = 1; i <= 1000000; i++)
                System.out.print("1");
            System.out.println();
        }
    }
    
    void two() {
        synchronized(this) {
            for (int i = 1; i <= 1000000; i++)
	            System.out.print("2");
            System.out.println();
        }
    }

    ...
インスタンス単位で同期をとる必要がない場合もあるので、staticクラス単位で同期をとれないか検討すること。