例えば、以下のように処理を1つずつ順番に実行するよう制御するような用途で利用することができます。

SyncronizedThread クラスは、処理を実行するクラスで、ThreadSyncronizer というクラスの機能を利用して同時実行制御が行われます。
public class SyncronizedThread implements Runnable { // スレッド同時実行制御クラス private ThreadSyncronizer threadSyncronizer; // カウンタ private int count; // コンストラクタ public SyncronizedThread(int count) { this.count = count; threadSyncronizer = ThreadSyncronizer.getInstance(); } public void run() { // ロックの取得 threadSyncronizer.lock(); // 処理の実行 try { System.out.println("Thread(" + count + ") Run!"); Thread.sleep(1000); System.out.println("Thread(" + count + ") End!"); } catch (Exception e){ e.printStackTrace(); } // ロックの解放 threadSyncronizer.unlock(); } }このクラスは Runnable インターフェースを実装しており、スレッドとして実行されますが、run() の中で処理の実行の前後に、ThreadSyncronizer クラスの lock() と unlock() を呼び出しています。
処理を実行する前に、他の処理が実行されないようロックを掛け、処理が完了したらロックを解放するというわけです。
このクラスで利用している ThreadSyncronizer クラスは、スレッドの同時実行制御を行うクラスで、Guarded Suspension パターンのキモになるクラスです。
public class ThreadSyncronizer { // インスタンス private static ThreadSyncronizer threadSyncronizer = new ThreadSyncronizer(); // 実行可否 private boolean available = true; // コンストラクタ private ThreadSyncronizer() {} /** * インスタンスを取得する。 * * @return ThreadSyncronizer */ public static ThreadSyncronizer getInstance() { return threadSyncronizer; } /** * ロック */ public synchronized void lock() { while (available == false) { try { wait(); } catch (InterruptedException e) { } } available = false; } /** * ロック解放 */ public synchronized void unlock() { available = true; notify(); } }
lock() は処理の実行前に呼び出され、処理が実行可能な状態かどうかを判定する条件(ガード条件)をチェックします。
ガード条件がifではなく、while ループでチェックするのがポイントです。
ガード条件を満たす場合は、while ループを抜けます。
ガード条件が満たされない場合は、wait() が呼び出されて待機状態になり、他のスレッドによる notify() の呼び出しによって呼び起されてガード条件を再度チェックします。
unlock() は処理の実行後に呼び出され、notify() を呼び出して待機状態のスレッドを再開します。
この2つのクラスを使った Guarded Suspension パターンの動きは、シーケンス図で表すと以下のような感じになります。

実際に動かしてみます。
public class TestGuardedSuspension { // Guarded Suspensionパターンによるスレッド同時実行制御 public static void main(String[] args) { // スレッドの呼び出しを10回繰り返す。 for (int i = 1; i <= 10; i++){ System.out.println("Thread(" + i + ") Start!"); new Thread(new SyncronizedThread(i)).start(); } } }
SyncronizedThread クラスのスレッドの呼び出しを 10 回繰り返します。
Thread(1) Start! Thread(2) Start! Thread(3) Start! Thread(1) Run! Thread(4) Start! Thread(5) Start! Thread(6) Start! Thread(7) Start! Thread(8) Start! Thread(9) Start! Thread(10) Start! Thread(1) End! Thread(2) Run! Thread(2) End! Thread(3) Run! Thread(3) End! Thread(4) Run! Thread(4) End! Thread(5) Run! Thread(5) End! Thread(6) Run! Thread(6) End! Thread(7) Run! Thread(7) End! Thread(8) Run! Thread(8) End! Thread(9) Run! Thread(9) End! Thread(10) Run! Thread(10) End!スレッドは一気に開始されますが、処理は1つずつ順番に実行されることが確認できます。