読者です 読者をやめる 読者になる 読者になる

Javaスレッドで異なるインスタンスでも同期するためには

Javaでスレッドで同期するにはsynchronizedを使用するが、

synchronized public void foo() {
	....
}

public void foo() {
	synchronized (this) {
		....
	}
}

とした場合、同じインスタンスでの同期となる。
スレッドが異なるインスタンスを使用して同期しなきゃいけない時は、同期用オブジェクトをsynchronizedに指定してやれば良い。例ではクラス変数を参照して同期している。

package com.foobar.console;

/**
 * スレッド同志で異なるインスタンスでも同期できるかのテスト
 */
public class Test00 {
	private static final int MAX_THREAD = 500;
	public static int counter = 0;
	public static final Object LOCK = new Object();	// 同期用オブジェクト
	
	public static void main(String[] args) {
		// スレッド生成
		MyThread[] threads0 = new MyThread[MAX_THREAD];
		MyThread[] threads1 = new MyThread[MAX_THREAD];
		for (int i = 0; i < MAX_THREAD; i++) {
			threads0[i] = new MyThread(new Counter());
			threads1[i] = new MyThread(new Counter());
			threads0[i].start();
			threads1[i].start();
		}
		// スレッドが全て終了するのを待つ
		for (int i = 0; i < MAX_THREAD; i++) {
			try {
				threads0[i].join();
				threads1[i].join();
			} catch (InterruptedException e) {
				System.out.println(e);
			}
		}
		// カウンタを表示
		System.out.println(counter);
	}
}

/**
 * スレッドクラス
 */
class MyThread extends Thread {
	private Counter counter = null;

	public MyThread(Counter counter) {
		this.counter = counter;
	}

	public void run() {
		this.counter.countUp();
	}
}

/**
 * カウンタクラス
 */
class Counter {
	public void countUp() {
		synchronized (Test00.LOCK) {
			System.out.print(".");
			int n = Test00.counter;	// カウンタ値を読み込み
			System.out.print("o");
			Test00.counter = n + 1;	// 加算してカウンタに設定
			System.out.print("O");
		}
	}
}

参考にしたのは以下のサイト。

http://www.tohoho-web.com/java/thread.htm#synchronized