コードを並列に実行するタスクの開発
Callable または Runnable でコードをラップしてから管理対象 executor にサブミットまたはスケジュールすることによって、操作を並列に実行できます。
始める前に
オプションで、管理者は管理コンソールを使用して、少なくとも 1 つの作業マネージャーを構成するか、デフォルト作業マネージャーの設定を変更することができます。
このタスクについて
コードを並列に実行するには、Callable または Runnable でコードをラップしてから管理対象 executor にサブミットまたはスケジュールします。
手順
- Callable タスクまたは Runnable タスクを実装します。
タスクは、java.util.concurrent.Callable インターフェースまたは java.lang.Runnable インターフェースを実装します。例えば、 あるトピックに動的にサブスクライブするタスクと、任意のコンポーネントを作成することができます。
class SampleTask implements Callable<Object> { Set<MessageListener> listeners = Collections.newSetFromMap(new ConcurrentHashMap<MessageListener, Boolean>(); Topic targetTopic; TopicConnectionFactory tcf; public SampleWork(TopicConnectionFactory tcf, Topic targetTopic) { this.targetTopic = targetTopic; this.tcf = tcf; } public void addMessageListener(MessageListener listener) { listeners.add(listener); } public Object call() throws JMSException { // setup our JMS stuff.TopicConnection tc = tcf.createConnection(); try { TopicSession sess = tc.createSession(false, Session.AUTOACK); tc.start(); while( !Thread.currentThread().isInterrupted() ) { // block for up to 5 seconds. Message msg = sess.receiveMessage(5000); if(msg != null) for (MessageListener listener : listeners) listener.onMessage(msg); } tc.close(); } finally { if (tc != null) tc.close(); } } }
この結果、どのコンポーネントもメッセージ・リスナーをオンデマンドで追加でき、これにより、 コンポーネントは、単に各クライアント・サブスクライバーに自身のスレッドを与えるよりもスケーラブルな方法でトピックにサブスクライブすることができます。
- このアプリケーション・コンポーネントが必要とする作業マネージャー数を判別します。
- java:comp 名前空間で、管理対象 executor、スレッド・ファクトリー、コンテキスト・サービスのリソース環境参照、または作業マネージャーのリソース参照 (または論理名) を使用して、
作業マネージャーをルックアップします。(リソース環境参照およびリソース参照について詳しくは、『参照』トピックを参照してください)
管理対象 executor のリソース環境参照 (このケースでは concurrent/myWorkManager) は、 アプリケーション・デプロイメント記述子または @Resource アノテーションでリソース環境参照として宣言される必要があります。InitialContext ic = new InitialContext(); ManagedExecutorService executor = (ManagedExecutorService)ic.lookup("java:comp/env/concurrent/myWorkManager");
- パラメーターとして Callable タスクまたは Runnable タスクのインスタンスを使用して ManagedExecutorService.submit() メソッドを呼び出します。 以下に例を示します。
Callable<Boolean> task = new MyTask(...); Future<Boolean> future = executor.submit(task);
Future は、コンポーネントとサブミットされたタスクとをリンクするハンドルです。
- オプション: アプリケーション・コンポーネントが 1 つ以上のタスクの完了を待機する必要がある場合は、Future.get() メソッドを呼び出します。 以下に例を示します。
Future<String> futureA = executor.submit(taskA); Future<String> futureB = executor.submit(taskB); futureA.get(5, TimeUnit.SECONDS); futureB.get(5, TimeUnit.SECONDS);
あるいは、invokeAll() メソッドを使用して、複数のタスクをサブミットし、それらすべてが完了するのを待機します。以下に例を示します。
tasks = Arrays.asList(taskA, taskB); futures = executor.invokeAll(tasks, 5, TimeUnit.SECONDS); // we can check future.isDone() to see which, if any, finished.
このメソッドには、すべての作業オブジェクトが完了するのをコンポーネントが待機するタスクの集合を指定します。タイムアウト値を指定することもできます。
- Future.cancel(true) メソッドを使用して、タスクの中断を試みます。
中断に対して即時に対応するか、できるだけ早く実行を中止するよう試みるために、タスクを実装します。
サブトピック
Callable タスクおよび Runnable タスク
Concurrency Utilities for Java EE では、サブミットしているスレッドの Java Platform, Enterprise Edition (Java EE) コンテキストと並行してコードを実行するために、Callable タスクまたは Runnable タスクがアプリケーション・コンポーネントによって使用されます。例: Callable タスクおよび Runnable タスクの作成
トピックに動的にサブスクライブするタスクを作成することができ、 任意のコンポーネントはメッセージ・リスナーをオンデマンドで追加できます。例: 並行性と接続の使用
Runnable または Callable は、それが作成するコンポーネントが java:comp リソース参照を使用して取得した接続を使用できます。


http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tasb_devwkobj
ファイル名:tasb_devwkobj.html