プログラム悪戦苦闘日記

はてなダイアリーからの移行(遺物)

スレッドデザインパターン - Producer-Consumer -

 
TableクラスをLinkedBlockingQueueで実装した。EaterThreadでは要素を取り出すとき、空の場合は待機してほしいので、poll()ではなくtake()を使った。poll()にすると、要素がないときブロックせずにnullを返してしまう。また、MakerThreadのid_はロックする必要があるのでLock(ミューテックス)でくくる必要がある。

package dp.chap05;

import java.util.concurrent.*;

public class Main {
	public static void main(String[] args) {
		BlockingQueue<String> table = new LinkedBlockingQueue<String>();
		
		new MakerThread("MakerThread-1", table).start();
		new MakerThread("MakerThread-2", table).start();
		new MakerThread("MakerThread-3", table).start();
		new EaterThread("EaterThread-1", table).start();
		new EaterThread("EaterThread-2", table).start();
		new EaterThread("EaterThread-3", table).start();
	}
}
package dp.chap05;

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.*;

public class MakerThread extends Thread {
	private final Random 					random_ = new Random();
	private final BlockingQueue<String> 	table_;
	
	private static int 	id_ 	= 0;
	private static Lock	mutex_ 	= new ReentrantLock();
	
	public MakerThread(String name, BlockingQueue<String> table) {
		super(name);
		table_	= table;
	}
	
	public void run() {
		try {
			while(true) {
				sleep(random_.nextInt(1000));
				String cake = "[ Cake No." + nextID() + " by " + getName() + "]";
				table_.put(cake);
				System.out.println(getName() + " puts " + cake);
			}
		}catch(InterruptedException ie) {
		}
	}
	
	private static int nextID() {
		mutex_.lock();
		try { return id_++; }
		finally { mutex_.unlock(); }
	}
}
package dp.chap05;

import java.util.*;
import java.util.concurrent.*;

public class EaterThread extends Thread {
	private final Random 				random_ = new Random();
	private final BlockingQueue<String>	table_;
	
	public EaterThread(String name, BlockingQueue<String> table) {
		super(name);
		table_ = table;
	}
	
	public void run() {
		try {
			while(true) {
				String cake = table_.take();
				sleep(random_.nextInt(1000));
				System.out.println(getName() + " takes " + cake);
			}
		}catch(InterruptedException ie) {
		}
	}
}

実行結果

MakerThread-1 puts [ Cake No.0 by MakerThread-1]
MakerThread-2 puts [ Cake No.1 by MakerThread-2]
MakerThread-1 puts [ Cake No.2 by MakerThread-1]
EaterThread-1 takes [ Cake No.0 by MakerThread-1]
MakerThread-3 puts [ Cake No.3 by MakerThread-3]
EaterThread-3 takes [ Cake No.2 by MakerThread-1]
MakerThread-3 puts [ Cake No.4 by MakerThread-3]
MakerThread-3 puts [ Cake No.5 by MakerThread-3]
MakerThread-2 puts [ Cake No.6 by MakerThread-2]
EaterThread-2 takes [ Cake No.1 by MakerThread-2]
EaterThread-1 takes [ Cake No.3 by MakerThread-3]
MakerThread-1 puts [ Cake No.7 by MakerThread-1]
MakerThread-1 puts [ Cake No.8 by MakerThread-1]
EaterThread-1 takes [ Cake No.6 by MakerThread-2]
MakerThread-3 puts [ Cake No.9 by MakerThread-3]
EaterThread-3 takes [ Cake No.4 by MakerThread-3]
MakerThread-3 puts [ Cake No.10 by MakerThread-3]
MakerThread-2 puts [ Cake No.11 by MakerThread-2]
EaterThread-2 takes [ Cake No.5 by MakerThread-3]
MakerThread-3 puts [ Cake No.12 by MakerThread-3]
MakerThread-1 puts [ Cake No.13 by MakerThread-1]
EaterThread-2 takes [ Cake No.9 by MakerThread-3]
EaterThread-3 takes [ Cake No.8 by MakerThread-1]
EaterThread-1 takes [ Cake No.7 by MakerThread-1]
MakerThread-3 puts [ Cake No.14 by MakerThread-3]
MakerThread-2 puts [ Cake No.15 by MakerThread-2]
MakerThread-3 puts [ Cake No.16 by MakerThread-3]
MakerThread-1 puts [ Cake No.17 by MakerThread-1]
MakerThread-3 puts [ Cake No.18 by MakerThread-3]
EaterThread-2 takes [ Cake No.10 by MakerThread-3]
MakerThread-3 puts [ Cake No.19 by MakerThread-3]
EaterThread-1 takes [ Cake No.12 by MakerThread-3]
EaterThread-3 takes [ Cake No.11 by MakerThread-2]
MakerThread-2 puts [ Cake No.20 by MakerThread-2]
EaterThread-1 takes [ Cake No.14 by MakerThread-3]
EaterThread-1 takes [ Cake No.16 by MakerThread-3]
MakerThread-1 puts [ Cake No.21 by MakerThread-1]
EaterThread-2 takes [ Cake No.13 by MakerThread-1]
EaterThread-2 takes [ Cake No.18 by MakerThread-3]
MakerThread-3 puts [ Cake No.22 by MakerThread-3]
MakerThread-2 puts [ Cake No.23 by MakerThread-2]