S2JMS 開発記 WorkManager と CountDownLatch
S2JMS 開発記といいつつ,当分は S2JCA 開発記.
まずは「10. Work Management」から.
ここでの主要な存在は javax.resource.spi.work.WorkManager
です.
これは java.util.concurrent.Executor
と近い代物で,重めの処理をバックグラウンドのスレッドで実行してもらうためのもの.
話を JMS による非同期メッセージングに限定して書くと,メッセージを受信した JMS リソースアダプタはそれを javax.jms.MessageListener
を実装したアプリケーションっていうか MDB に渡して処理してもらうのですが,その際にメッセージを受信したスレッドではなく,アプリケーションサーバが管理するスレッドで処理してもらうことが想定されているっぽい.
そのために使われるのが WorkManager
.
実際にはメッセージの処理以外のことでもなんでもありで,とにかくリソースアダプタは自前でスレッド起こしたりせずに,何かあったら WorkManager
にお願いする次第.
んで,WorkManager
にはこんなメソッドがあります.
doWork(Work work)
startWork(Work work)
scheduleWork(Work work)
Work
は Runnable
を拡張したもので,アプリケーションサーバが提供するスレッド上で実行する処理を表します.
それぞれのメソッドの複雑版もあるのですが,これらの違いは
doWork(Work)
- 別スレッドで
Work
の実行が終了した時点でリターンする. startWork(Work)
- 別スレッドで
Work
の実行が開始された時点でリターンする. scheduleWork(Work)
WorkManager
がWork
を受け付けた時点でリターンする.
となっています.
つまり,単純にスレッドプールに Work
をキューイングして終わりじゃなくて,開始時点や終了時点で同期をとらないといけないわけですね.
こういうのって,自分で同期してもたいした手間ではないのですが,これまで J2SE1.4 前提だったために使う機会の無かった java.util.concurrent
パッケージをチェックしてみたら,そのものズバリなクラスがありました.
java.util.concurrent.CountDownLatch
です.
こいつは整数の値を持っていて,await()
メソッドを呼び出すと整数値が 0 になるまでブロックします.
別のスレッドが countDown()
メソッドを呼び出すと整数値が -1
され,0 になれば await()
しているスレッドが起こされます.
なので,doWait(Work)
では 2,startWork(Work)
では 1,scheduleWork(Work)
では 0 に設定した CountDownLatch
を使って,Work
の実行前後に countDown()
を呼び出すようにすれば簡単に実装できそう (整数値が 0 の時に countDown()
を呼び出しても問題なし).
昔 (Doug Lea の) はバイナリの Latch
しかなかった気がするけど,こっちの方が強力ですね.
スレッドプールもいくつかの実装が用意されているし,便利そうだなぁ java.util.concurrent
パッケージ.
Tiger を使う機会が無くてかなーり出遅れたけど,これらもうまく使えるようにならなきゃ.
とりあえず,正月休み中に「10. Work Management」を終わらせたい今日この頃であります.