Java EE開発について最初に学んだことの1つは、独自のスレッドをJava EEコンテナ内に生成すべきではないということです。それについて考えに来て、私は理由を知りません。
落胆した理由を明確に説明できますか?
ほとんどのエンタープライズアプリケーションには、メールデーモン、アイドルセッション、クリーンアップジョブなどの非同期ジョブが必要だと思います。
それで、本当にスレッドを生成するべきではない場合、必要なときにそれを行う正しい方法は何ですか?
環境内のすべてのリソースはサーバーによって管理され、場合によっては監視されるため、推奨されません。また、スレッドが使用されているコンテキストの多くは、通常、実行自体のスレッドに関連付けられています。単純に独自のスレッドを開始すると(一部のサーバーでは許可されないこともあると思います)、他のリソースにアクセスできません。つまり、InitialContextを取得してJNDIルックアップを実行し、JMS接続ファクトリーやデータソースなどの他のシステムリソースにアクセスすることはできません。
これを「正しく」行う方法はありますが、使用しているプラットフォームによって異なります。
commonj WorkManagerは、WebSphereおよびWebLogicおよびその他の共通です
またやや重複 this one 今朝から
更新:この質問と回答は、2009年のJava EEの状態に関連しているため、状況は改善されています。
EJBの場合、推奨されていないだけでなく、 specification によって明示的に禁止されています。
エンタープライズBeanは、スレッド同期プリミティブを使用して複数のインスタンスの実行を同期してはなりません。
そして
エンタープライズBeanは、スレッドの管理を試みてはなりません。エンタープライズBeanは、スレッドの開始、停止、一時停止、再開を試みたり、スレッドの優先度や名前を変更したりしてはなりません。エンタープライズBeanは、スレッドグループの管理を試みてはなりません。
その理由は、EJBは分散環境で動作することを意図しているためです。 EJBは、クラスター内のあるマシンから別のマシンに移動される場合があります。スレッド(およびソケットおよびその他の制限された機能)は、この移植性に対する大きな障壁です。
独自のスレッドを生成しないのは、これらのスレッドがコンテナによって管理されないためです。コンテナは、初心者の開発者が想像しにくい多くのことを処理します。たとえば、スレッドプーリング、クラスタリング、クラッシュリカバリなどは、コンテナによって実行されます。スレッドを開始すると、それらのいくつかを失う可能性があります。また、コンテナを使用すると、実行するJVMに影響を与えずにアプリケーションを再起動できます。コンテナの制御外のスレッドがある場合、これはどのように可能ですか?
これが、J2EE 1.4タイマーサービスが導入された理由です。詳細については、 this の記事を参照してください。
コアJava EE APIを使用してスレッドを作成する標準の正しい方法があります。
Concurrency Utilsを使用することにより、新しいスレッドがコンテナーによって作成および管理され、すべてのEEサービスが利用可能であることが保証されます。
例 ここ
そうしない本当の理由はありません。 Webアプリで Quarz with Spring を問題なく使用しました。同時実行フレームワークJava.util.concurrent
を使用できます。独自のスレッド処理を実装する場合は、theadsを deamon に設定するか、独自のデーモンスレッドグループを使用して、コンテナがいつでもwebappをアンロードできるようにします。
ただし、Beanスコープsessionおよびrequestは機能しませんスレッドが生成されました!また、 ThreadLocal
で実行される他のコードは、そのままでは機能しません。自分で生成されたスレッドに値を転送する必要があります。
デプロイメント記述子の一部として、いつでもコンテナを起動するようにコンテナに指示できます。これにより、必要なメンテナンスタスクを実行できます。
ルールに従う。いつかあなたがしたことを喜んでいるでしょう:)
Java EEコンテナは設計図に従って禁止されています。詳細については blueprints を参照してください。
EJBでスレッドをいくつか生成し、コンテナをアンロードまたは更新しようとすると、問題が発生する理由の1つです。ほとんど常に、スレッドを必要としない場所で何かをする別の方法があるので、NOとだけ言ってください。
正しく行うのは容易ではないという事実を除いて、それが落胆しているとは読んだことがありません。
それはかなり低レベルのプログラミングであり、他の低レベルのテクニックと同様に、正当な理由が必要です。ほとんどの同時実行性の問題は、スレッドプールなどの組み込み構造を使用して、はるかに効率的に解決できます。