#navi_header|Java| EJBとかJMSのような実践的なJavaEEは今まで触らず、もっぱらServletプログラミングばかり触ってましたが、最近になって「新しいJavaEEでは非同期処理がサポートされた!」とか目にしまして、「アレ?JavaEE環境ってスレッド作成しちゃ駄目だったの?」と今頃になって気になり、ちょっと調べてみました。 * 結論 JavaEE7使おうぜ! or JavaEEコンテナ環境を当てにせず独自実装で頑張ろう! - JavaEE5以前 : 非推奨。 - JavaEE6 : Servlet 3.0にて非同期処理に対応したので、スレッドっぽく使えそう。 - JavaEE7 : EJB/JMS/Servletをサポートした、"Concurrency Utilities for JavaEE(JSR-236)"の導入により、正式にスレッド生成をサポート * JavaEE5以前 JavaEE5以前は、ServletやEJBなどJavaEE側でコンテナとして管理される仕組みではスレッドはなるべくコンテナ側で管理される仕組みを目指しているため、アプリ側で好き勝手にスレッド作るのは好ましくないようでした。JavaEE6になりServletで一部、非同期処理に対応したためスレッドっぽく使えるようになったようです。そのような状況でしたので、JavaEE7になり正式にスレッド生成をサポートするようになったのが、特にニュースになったようです。 「好ましくない」という言い方ですが、モノによっては「禁止」まで名言されてたりされてなかったりするようです。EJBだと以前の仕様では禁止と明記されてたり、Servletの仕様だと「好ましくない」にとどまってたり微妙に有耶無耶。ただ、あんまり「new Threadしたらコンテナ側からエラーで怒られた!」とかいう話は見当たらなかったので、コンテナ側のポリシー設定で禁止してるとかそういう話はみかけませんでした。(もしかしたら一部のJ2EEコンテナ製品ではそうした設定があったりして、単に検索で引っかからなかっただけかも) 理解した範囲で、技術的な背景を説明するなら、EJBにせよServletにせよ、スレッドローカルにコンテナ側で生成したオブジェクトを入れてる仕組みが多いようです。そのため、アプリ側で好き勝手に作られたスレッド中から、本来ならコンテナ側で管理してるオブジェクトを参照していたりすると、スレッドが動くタイミングではコンテナ側でクリアしていてNullPointerExceptionになってしまったりと、予測できない動きになってしまうケースがあるようです。 そのため、スレッドの作成をするのであればJavaEE環境の恩恵は受けられないことを前提として、必要なオブジェクトは自分たちでちゃんと引き継いで、スレッドの管理も含めて自分たちで面倒見てくださいね、何かあってもJavaEE側は知りませんよ、というスタンスみたいです。 分かりやすかった日本語解説ページ: - Java EE環境における非同期プログラミング - nekopの日記 -- http://d.hatena.ne.jp/nekop/20120417/1334654442 - Servletがスレッドを生成してはいけないのか | code up -- http://frmmpgit.blog.fc2.com/blog-entry-93.html Servletの世界の場合ですと、ServletContextListener使うのが地雷回避っぽいですね。 stackoverflowでもチラホラトピックに挙がってました。 - java - I need a thread in Web/JavaEE container to complete AsyncContext objs in same JVM - Stack Overflow -- http://stackoverflow.com/questions/10276028/i-need-a-thread-in-web-javaee-container-to-complete-asynccontext-objs-in-same-jv - java - Thread creation in JavaEE EJB/Web containers - Stack Overflow -- http://stackoverflow.com/questions/13161634/thread-creation-in-javaee-ejb-web-containers - multithreading - Why spawning threads in Java EE container is discouraged? - Stack Overflow -- http://stackoverflow.com/questions/533783/why-spawning-threads-in-java-ee-container-is-discouraged * JavaEE6時代 JavaEE6に含まれた Servlet 3.0 において、非同期APIが導入されました。とはいえ、スレッド生成がサポートされた訳ではないようです。 - Java EE 6の話 -ありえるえりあ勉強会- — ありえるえりあ -- http://dev.ariel-networks.com/articles/workshop/javaee6/ - Java EE 6のWeb層:サーブレットが非同期をサポートし、拡張性が改善 -- http://www.infoq.com/jp/news/2010/01/ee6_servlet30 * JavaEE7になって "Concurrency Utilities for JavaEE(JSR-236)"の導入により、正式にスレッド生成をサポート・・・つまり、JavaEEコンテナ側でスレッド管理されて、JavaEEコンテナ側で管理されてるリソースが生成されたスレッドから参照可能になる・・・ということでよろしいでしょうか・・・。 JSR-236とか目を通してないし、多分現場レベルでの情報が出てくるのはこれからだと思いますので、今日のところはここまで。 - リリース間近!Java EE 7の気になるところ - DENのシステムエンジニアの思うこと -- http://den2sn.hatenablog.com/entry/2013/04/25/075201 - 祝! Java EE 7リリース | Mushagaeshi.com | 武者返し.com -- http://www.mushagaeshi.com/2013/06/12/java-ee-7-released/ - Java EE 7 Detail -- http://www.slideshare.net/OracleMiddleJP/java-ee-7-detail #navi_footer|Java|