スレッドデザインパターン - Producer-Consumer -
TableクラスをLinkedBlockingQueue
- Main.java
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(); } }
- MakerThread.java
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(); } } }
- EaterThread.java
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]