Guarded Suspensionパターン
* 処理要求に対して、実行可能な状態になるまで待機させるデザインパターン => インスタンスが適切な状態になるまで、ガード条件を使ってスレッドを待たせる * ガード条件が変化したことをスレッドの通知(notify/notifyAll)
関連するパターン
* Balkingパターン:ガード条件が満たされないなら待たずに返る場合http://blogs.yahoo.co.jp/dk521123/34200869.html
補足:スレッドの同期
http://blogs.yahoo.co.jp/dk521123/32058018.html* wait() : 現在のスレッドを待機させる。 * notify() : wait()によって待機中であるスレッドの1つを再開。プログラム側から指定することはできない。 * notifyAll() : wait()によって待機中であるすべてのスレッドを再開。
サンプル
Main.java
public class Main { public static void main(String[] args) { TaskManager manager = TaskManager.getInstance(); for (int i = 1; i <= 10; i++) { System.out.println("workThread(" + i + ") put!"); TaskThread workThread = new TaskThread(manager, i); manager.putTask(workThread); System.out.println("workThread(" + i + ") Start!"); TaskThread workThread2 = manager.getTask(); workThread2.start(); } } }
TaskManager.java
import java.util.concurrent.atomic.AtomicBoolean; public class TaskManager { private static TaskManager manager = new TaskManager(); private TaskQueue taskQueue; private AtomicBoolean isAvailable = new AtomicBoolean(true); private TaskManager() { this.taskQueue = new TaskQueue(); } public static TaskManager getInstance() { return TaskManager.manager; } public TaskThread getTask() { return this.taskQueue.getTask(); } public synchronized void putTask(TaskThread task) { this.taskQueue.putTask(task); } /** * ロック */ public synchronized void lock() { while (!this.isAvailable.get()) { try { this.wait(); } catch (InterruptedException e) { } } this.isAvailable.set(false); } /** * ロック解放 */ public synchronized void unlock() { this.isAvailable.set(true); this.notify(); } }
TaskThread.java
public class TaskThread extends Thread { private TaskManager manager; private int id; // コンストラクタ public TaskThread(TaskManager manager, int id) { this.manager = manager; this.id = id; } public void run() { this.manager.lock(); // 処理の実行 try { System.out.println("Thread(" + id + ") Run!"); Thread.sleep(1000); System.out.println("Thread(" + id + ") End!"); } catch (Exception e) { e.printStackTrace(); } this.manager.unlock(); } }
TaskQueue.java
import java.util.Queue; import java.util.LinkedList; public class TaskQueue { private final Queue<TaskThread> queue = new LinkedList<TaskThread>(); public synchronized TaskThread getTask() { while (this.queue.peek() == null) { try { this.wait(); } catch (InterruptedException e) { } } return this.queue.remove(); } public synchronized void putTask(TaskThread task) { this.queue.offer(task); } }
参考文献
http://ameblo.jp/archive-redo-blog/entry-10133382795.htmlhttp://pgcafe.moo.jp/JAVA/thread/main_2.htm
http://d.hatena.ne.jp/otuzak/20080527/1211864889
http://blog.codebook-10000.com/entry/20130216/1360990136