マイナー・マイナー

隠れた名作の発掘が生きがい。

インスタンスメソッドとstaticメソッドのロック


スポンサードリンク

Javaのスレッドが実行するメソッドはsynchronizedキーワードを用いることによってロックすることができます.ロックはインスタンスメソッドとstaticメソッドにかけることができます.


サンプルプログラムを以下に示します.Printクラスのrunメソッド内でインスタンスメソッドであるprintA,staticメソッドであるprintBをそれぞれ指定して呼び出すように実装しました.また,mainではスレッドの実行にスレッドごとにPrintオブジェクトを生成して指定する方法(test1),複数のスレッドがひとつのPrintオブジェクトを指定する方法(test2)を指定するように実装しました.

サンプルプログラム

class Print implements Runnable{

	public void run() {
		printA();
		//printB();
	}
	
	private synchronized void printA() {
		print();
	}
	
	private static synchronized void printB() {
		print();
	}
	
	private static void print() {
		for (int i = 0; i < 3; i++) {
			System.out.print(i + " ");
		}
		System.out.println("");
	}
}

public class SynchronizedTest {

	public static void main(String[] args) {
		//test1
		for (int i = 0; i < 10; i++) {
			new Thread(new Print()).start();
		}
		
		//test2
		//Print print = new Print();
		//for (int i = 0; i < 10; i++) {
		//	new Thread(print).start();
		//}
	}
}


実行結果1(printA,test1を指定)


0 0 1 2
0 1 2
0 1 2
0 1 2
1 2
0 1 0 2 1
2 0 0 1
2 1
2
0 1 2


実行結果2(printA,test2を指定)


0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2


実行結果1は,スレッドごとにPrintオブジェクトを持っているため,各スレッドがprintBメソッドを非同期に実行した結果を示しています.実行結果2は,ひとつのPrintオブジェクトのprintBメソッドに各スレッドが非同期にアクセスしますが,printBが終わるまでロックをかけているために012の表示が続きます.また,printCはtest1でもtest2でも実行結果は実行結果2のように012が続きます.