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

以下のSyncTest1クラス内のstaic synchronizedであるone, two, three3つのメソッドは、同時には実行されず、必ず一つづつ実行される。
public class SyncTest1 {

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

    static synchronized void three() {
        for (int i = 1; i <= 1000000; i++) {
            System.out.print("3");
            if (i % 100 == 0) System.out.println();
        }
    }

    public static void main(String[] args) {

        long lStart = System.nanoTime();
    	
        ExecuteOne exeOne = new ExecuteOne();
        ExecuteTwo exeTwo = new ExecuteTwo();
        ExecuteThree exeThree = new ExecuteThree();

        exeOne.start();
        exeTwo.start();
        exeThree.start();
        
        try {
            exeOne.join();
            exeTwo.join();
            exeThree.join();
        }
        catch (InterruptedException ie) {
            ie.printStackTrace();
        }

        System.out.println(System.nanoTime() - lStart);
    }
}

class ExecuteOne extends Thread {
    public void run() {
        SyncTest1.one();
    }
}

class ExecuteTwo extends Thread {
    public void run() {
        SyncTest1.two();
    }
}

class ExecuteThree extends Thread {
    public void run() {
        SyncTest1.three();
    }
}

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

    static void one() {
        synchronized(Class.forName("SyncTest1")) {
            for (int i = 1; i <= 1000000; i++) {
                System.out.print("1");
                if (i % 100 == 0) System.out.println();
            }
        }
    }
    
    static void two() {
        synchronized(Class.forName("SyncTest1")) {
            for (int i = 1; i <= 1000000; i++) {
	            System.out.print("2");
                if (i % 100 == 0) System.out.println();
            }
        }
    }

    static void three() {
        synchronized(Class.forName("SyncTest1")) {
            for (int i = 1; i <= 1000000; i++) {
                System.out.print("3");
                if (i % 100 == 0) System.out.println();
            }
        }
    }

    ...
メソッド単位で同期をとるのではなくて、staticクラス単位で同期をとるということ。

ちなみに、synchronized(Class.forName("SyncTest1"))は、synchronized(Class.forName("SyncTest1"), true, currentLoader)と書くのと同義。