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