HiveMind:マルチスレッド |
HiveMind は、はっきりと WAR や EAR のデプロイという J2EE を目標に定めており、特に Tapestry アプリケーションの一部として意識しています。勿論、J2EEは必須条件ではありませんし、HiveMind は単体であってもシンプルな環境でも非常に使い勝手の良いものに仕上がっています。
J2EEの世界に於いて、マルチスレッドという概念は常に話題に上ります。HiveMind サービスは通常シングルトンで、マルチスレッド環境に於いて実行されるよう準備されていなければなりません。つまり、サーブレット同様、サービス自体が特定の段階(状態)を持っているべきではない、という事になります。
コンストラクション段階
HiveMind では、一つの起動スレッドで初期の処理が進行していく事が予定されています。これは、初期段階・モジュールのデプロイ記述子の場所確認・解析されたところのコンストラクションの段階・そしてレジストリを集めるのに使われる内容であります:RegistryBuilderのドメインです。
コンストラクション自体はスレッドセーフではありません。これには、パーサーやその他のコード(事実上、その全てがアプリケーションから隠されています)
コンストラクション段階は、RegistryBuilder が、constructRegistry() メソッドから Registry を返したときに終了します。
ランタイム段階
Registry とモジュールで起こる全ての事象はスレッドセーフでなければなりません。キーとなるメソッドは常に synchronized です。特に、 サービスをコンストラクトするメソッドやコンフィグ・ポイントをコンストラクトするメソッドはスレッドセーフです。インタセプタ・スタックをビルドするといった処理、コアとなるサービスの実装のインスタンス化、Java オブジェクトのXMLへの変換といった処理は、スレッドセーフで行われます。しかし、異なるスレッドが同時に他のサービスをビルドする可能性もあります。つまり、例えば、2つ以上の異なるサービスの為のインタセプタを同時に呼び出す事もあり得るため、インタセプタ・サービスの実装はスレッドセーフであるのです。
一方、XML<rules> によってコンストラクトされたJavaオブジェクトはスレッドセーフである必要がありません。というのも、コンストラクションは適切に synchronized な状態で行われるからです。・・・ただ一つのスレッドが XML を あらゆる一つのコンフィグ・ポイントで Java オブジェクトに変換するでしょう。
サービス状態の管理
サービスが単にbetweenメソッドの invoke 状態を維持しなければならない場合、いくつかの良いオプションがあります:
- サービスに渡されるあるいはサービスから戻ってくるオブジェクト内のデータを格納
- thread-local マップ内のデータを格納する為の、hivemind.ThreadLocalStorage サービスの使用
- threaded あるいは pooled サービス・モデルの使用:サービス・メソッドが invoke されている間その状態をキープするのをサービスに許可する