Java同時プログラミング(二)CountDownLatch


前回に続き、4人の労働者が車輪を組み立てる時、作業室に車輪が組み立てることができなければ、労働者は車輪が作業室の適切な位置に運ばれてから車輪を組み立てる作業を行うことができる.だから、Workerクラスに新しいCountDownLatch---tyreReadyLatchを加えて、
このロックをWorkerスレッドに伝えてください.タイヤが来る前に待機状態にしなければなりません.待たないと、このWorkerスレッドがエラーを出してしまい、その結果、この車のタイヤ組み立て全体が失敗します.だから呼び出さなければならない
tyreReadyLatch.await();

この文は、Workerスレッドがタイヤの到来を待っていることを保証します.
 
BlockingQueueは、現在の作業中にタイヤを置く位置をシミュレートします.タイヤを4つ置くことができると仮定します.このQueueにタイヤを4つ入れ、タイヤを運ぶ作業はmain関数で完了
for (int i = 0; i < 4; i++){
	tyries.offer(new Tyre(i));
	Thread.sleep(500);
}

OK,4つのタイヤが着席した後,次の文を呼び出し,tyreReadyLatchを解放し,初期化するとtyreReadyLatchロックのカウンタが1に設定されるので,tyreReadyCountのcountDown()メソッドを1回だけ呼び出す必要がある.4つのWorkerスレッドを教えて、タイヤの組み立て作業を行うことができます.
tyreReadyLatch.countDown();

次のコードシミュレーションWorkerスレッドは、アセンブリ作業が可能な「コマンド」を受け取った後、作業室からタイヤを取り出します.
Tyre tyre = tyries.take();

タイヤを手に入れた後、Workerスレッドの動作モードは、第1回の労働者がタイヤを組み立てる一節の動作と同じです.
 
複数のCountDownLatchを使用すると、1つのスレッドの動作状態をより正確に制御できることがわかります.CountDownLatchのawaitとcountDownメソッドを組み合わせて使用する必要があります.そうしないと、スレッドは常に待機状態になります.
 
最後に、完全なコードリストです.
 
public class Worker implements Runnable {
	private String name;
	static CountDownLatch workDoneLatch = new CountDownLatch(4);
	static CountDownLatch tyreReadyLatch = new CountDownLatch(1);
	static ArrayBlockingQueue<Tyre> tyries = new ArrayBlockingQueue<Tyre>(4);

	public Worker(String name) {
		this.name = name;
	}

	@Override
	public void run() {
		try {
			System.out.format("%s is waiting for tyre ready....%n", name);
			tyreReadyLatch.await();
			Tyre tyre = tyries.take();
			System.out.format("%s is assembling.%n", tyre);
			marshalTyre();
			System.out.format("%s is assembled.%n", tyre);
			workDoneLatch.countDown();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	private void marshalTyre() throws InterruptedException {
		Thread.sleep(new Random().nextInt(60000));
	}

	/**
	 * @param args
	 * @throws InterruptedException
	 */
	public static void main(String[] args) throws InterruptedException {

		ExecutorService executorService = Executors.newFixedThreadPool(4);
		long s = System.currentTimeMillis();
		String works[] = { "John Chembers", "Bill Gates", "Larry Page", "Ericsson Limited" };
		for (int i = 0; i < 4; i++)
			executorService.execute(new Worker(works[i]));

		for (int i = 0; i < 4; i++){
			tyries.offer(new Tyre(i));
			Thread.sleep(500);
		}
		tyreReadyLatch.countDown();

		workDoneLatch.await();
		System.out.format("the 4 tyres were assembled. costs %d ms.%n", System.currentTimeMillis() - s);
		executorService.shutdown();
	}
}

 
補助タイプタイヤ
class Tyre {

	private int id;

	public Tyre(int id) {
		this.id = id;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	@Override
	public String toString() {
		return "Tyre: " + id;
	}
}
 
[オリジナルコンテンツ、著作権所有、転載があれば、出典を明記してください.間違いがあれば、指摘してください.感謝に堪えません]