Comments
Description
Transcript
スレッドと並行処理
ADAM BIEN 写真: THOMAS EINBERGER/ GETTY IMAGES ア誕生当時から、同時に複数のアプ プリケーション・サーバーは、その スレッドの禁止 EJB 1.0仕様では、理由を説明しない まま、スレッドおよび同期プリミティブ リケーションに共有リソースを供給する を直接使用することが禁止されていま ことを目的としていました。CPU時間、 した。EJB 3.1仕様では、次のように、 ファイル・システム、RAMといった希少 より厳格な制約が示されています。 「エ なリソースが、複数のアプリケーション ンタープライズBeanは、スレッドを管 で共有されます。しかし、 リソースを公 理してはならない。エンタープライズ 平に共有するためには、デプロイされ Beanは、スレッドの開始、 ているアプリケーションか 停止、中断、再開、もしくは らの協力が必要です。 スレッドの制御 スレッドの優先度または E n t e r p r i s e スレッド の 作 成 を 名前の変更を行ってはな JavaBeans(EJB)1.0 制御できなければ、 らない。エンタープライズ 仕 様 で 導 入されたプロ Beanは、スレッド・グルー グラミング上の制約の1 スケーラビリティや プを管理してはならない」 つに、 「エンタープライズ パ フォーマ ン ス だ また、制約の厳格化の理 Beanは、新しいスレッドを けでなく、 堅牢性に 由が、次のように説明され 開始することも実行中の ています。 「これらのスレッ スレッドを終了することも も影響します。 ド管理機能は、EJBコンテ できない」 ( 117ページ) ナのために確保されるもの という規 定 が あります 。 とする。エンタープライズ 現在の一般的なクラウド・ Beanによるスレッド管理を許容した場 プラットフォームにおける制約は、この 合、実行環境を適切に管理するコンテナ Java EEプログラミング・モデルと類 の能力が損なわれる」 (599ページ) 似しています。1998年にEJB 1.0が 実 践 上 は 、ア プ リ ケ ー ション・ 発表されたときからアプリケーション・ サ ー バ ー で スレッド に 対 す る 直 接 サーバーはクラウドに対応していたと の 操 作 を 防 ぐ 簡 単 な 方 法 とし て 、 言うこともできるでしょう。 SecurityManagerを有効にする 注: 本記事で説明するサンプル・アプリ ことができます。これにより、java. ケーションのソース・コードは、こちらか lang.Threadのコンストラクタで、 らダウンロードできます。 S e c u r i t y M a n a g e rに対して許 ORACLE.COM/JAVAMAGAZINE ////////// JULY/AUGUST 2012 可 が 求 めら れ ます 。た だし、ほとん ど の アプリケ ー ション・サ ー バ ー は SecurityManagerを使用せずに運 用されるため、アプリケーションがこの 制約に違反することは容易であり、違 反することによる影響もありません。 また、 「エンタープライズBeanに よるスレッドの管理を許容した場合、 実行環境を適切に管理するコンテナ の能力が損なわれる」という表現は、 あまりにも控えめです。スレッドの作 成を制 御できなければ、スケーラビ リティやパフォーマンスだけでなく、 堅牢性にも影響します。スレッドの1 つ 1 つ がメモリを 消 費します 。そ の た め 、スレッド数 が 多 す ぎる場 合 は OutOfMemoryErrorが発生し、ス レッドを開始したアプリケーションの安 定性に影響があるだけでなく、アプリ ケーション・サーバー全体、ひいてはデ プロイされているアプリケーションの すべてがクラッシュする事態にもなり かねません。 一方、アプリケーション・サーバーで は、管理および監視下にあるスレッド・ プールに置かれたスレッドを再利用し ます。 「Stress Testing Java EE 6 Applications」で説明したように、定 期的にストレス・テストを実施し、そのテ スト結果を利用してアプリケーション・ サーバーのスレッド・プールを設定する ことで、OutOfMemoryErrorの発 生を確実に防ぐことができます。スレッ ド・プールを適切に設定することによ り、サーバーを過負荷にするような新し い要求を拒否できます。 Java Servlet 3.0をはじめとす る W e b 層 の 仕 様 で は 、スレッド 管 理 の 自 由 度 が より高くなって い ま す 。 Java Servlet 3.0、Java API for RESTful Web Services(JAX-RS)、 JavaServer Faces(JSF)の各仕様 では、スレッドに関連するプログラミング 上の制約はありません。とは言え、ビジ ネス層で制約があるスレッド関連コード をプレゼンテーション・ロジックやJava Management Extensions(JMX) Beanに移しても、問題はまったく解決 されません。これでは、EJB仕様にお ける有益な制約を小手先のテクニック で回 避しているに過ぎませ ん 。通 常 、 WebコンテナとEJB/Contexts and Dependency Injection(CDI)コン テナは同じJava仮想マシン(JVM)上 で実行されます。Webコンテナでスレッ ド作成を制御しなければ、やはりアプリ ケーションで問題が発生し、サーバーが クラッシュする可能性があります。 JAVA TECH 重要性を増す希少なリソースの一元管理のJava EE 6による実現 ABOUT US スレッドと並行処理 JAVA IN ACTION COMMUNITY //enterprise java / @Asynchronous Java EE 6より前のバージョンでは、 容易にスレッドを開始する正式な方法 53 @Stateless public class LongTask { @Asynchronous public void execute(){ //実際の処理の実行 } } 非同期(@Asynchronous) メソッドでは、次 のように、java.util.concurrent.Future のインスタンスを返すこともできます。 @Stateless @Stateless public class BatchTask { @Inject LongTask lt; public class LongTask { @Asynchronous public Future<String> execute(){ String result = ...; // 実際の処理の実行 return new AsyncResult<String> (result); } } FutureのJavadocでは、冒頭に「Future は、非同期計算の結果を表します」と記載され ており、これがFutureの役割を完全に説明 しています。Futureインスタンスは、呼び出 されるとただちに返されます。インスタンス の処理状況は、Future#isDoneメソッドと Future#isCancelledメソッドを使用して 確認できます。また、Future#getメソッドを 使用して戻り値を取得することもできます。タ スクが完了していない場合、Future#getの 呼び出しは、結果が計算されるまでブロックさ れます。 バッチ処理 voidメソッドに対して@Asynchronous を使用することは、自然に思われます。一方、 Futureを返すメソッドは、標準的な要求/応答 シナリオではそれほど有用でないように見えま す。@Asynchronousアノテーションが付加 されたメソッドはFutureインスタンスをただ ちに返すものの、Future#getの呼び出しで ブロックが発生します。 getメソッドを呼び出す代わりに、isDone を使用して結果を取得できるかどうか確認す ることも可能ですが、 これも最適な方法ではあ りません。クライアントがCPUサイクルを浪費 ORACLE.COM/JAVAMAGAZINE ////////// JULY/AUGUST 2012 } public void executeInBatch() { List<Future<String>> results = new ArrayList(); //parallelize for(int i=0;i<10;i++){ results.add(lt.execute()); } //gather for (Future<String> resultProxy : results) { try { resultProxy.get(); // use the result, or not } catch (Exception ex) { } } } 全てのリストをテキストで表示 することになります。 Futureが有用なシナリオは、バッチ処理に よる複数のタスク実行の並列化です。そのため には、@Asynchronousが付加されたメソッ ドを実行し、FutureをListにキャッシュし、最 後に結果を収集するステートレスEJB Beanが 必要です。このコードをリスト1に示します。 リスト1の第1のループでは、アプリケー ション・サーバーのスレッド・プールにいくつ かのタスクを送信しています。execute() メソッドではただちにFutureインスタンス が返されます。このFutureインスタンスを java.util.Listに格納します。第2のループ では、すべてのFutureインスタンスに対して Future#getを呼び出して結果を取得しよう としています。Future#getメソッドではN-1 回ブロックが実行されますが、この呼び出しは ただちに制御を返します。 BatchTask#executeBatchメソッド の実行にかかる時間は、もっとも長い時間がか かったLongTask#executeの計算時間と 同じになります。 リスト1は順次的処理を行うように見えます が、実際には異なります。第1のループでは、繰 り返しごとにタスクをワーカー・プールに渡し、 非同期的に実行しています。また、第2のループ では、Futureの各インスタンスに対して繰り返 し処理を実行します。その際、タスクが計算され ていない場合はブロックが発生しますが、計算 結果を待機している間も、他のすべてのタスク はバックグラウンドで実行され続けます。 JAVA TECH はありませんでした。そのため、同期的なEJB Beanを非同期的に実行するために、Service A c t i v a t o rパターンとJ a v a M e s s a g e Service(JMS)が(不適切に)利用されていま した。 Service Activatorは、概念的にはGang of Four(GoF)によるDecoratorパターンの 1つですが、J2EEでの実現方法はあまりにも 複雑でした。まず、同期メソッドの呼び出しを、 EJB Beanとして実装されたプロキシによっ てJMSメッセージとしてエンコードする必要 があります。このJMSメッセージは一時的な 「応答キュー」を使用してメッセージ駆動型 Bean(MDB)に送信されます。このMDBは JMSランタイムによって非同期的に呼び出さ れます。onMessageメソッドによって、JMS メッセージがデコードされ、実際のEJBメソッド が非同期的に呼び出されます。 MDBは、実際のメソッドが実行を完了するまで 待機し、戻り値をJMSメッセージに変換して、その メッセージをプロキシに送り返します。このパター ンの実装は、1ページでは説明しきれないほど複雑 です。Service Activatorパターンは、一言で表す ならば、JMSを利用したローカルなリモート・プロ シージャ・コール(RPC)であると言えます。 EJB 3.1およびJava EE 6では、このよ うなService Activatorの実装を1つのアノ テーションに置き換えることができます。次の ように、voidメソッドに@Asynchronousア ノテーションを付加することで、そのメソッドを 非同期的に実行できます。 ABOUT US リスト1 JAVA IN ACTION COMMUNITY //enterprise java / ファイア・アンド・フォーゲットに有効 @ A s y n c h r o n o u sは、ファイア・アンド・ フォーゲット手法の実装に適しています。アプ リケーション・サーバーに送信されたタスクは 54 非同期サーブレット ORACLE.COM/JAVAMAGAZINE ////////// JULY/AUGUST 2012 リスト5 @Stateless public class PersistentAsynchronous { @Resource TimerService ts; public void executeAsync(String message){ TimerConfig config = new TimerConfig(message, true); ts.createSingleActionTimer(1, config); } @Timeout public void execute(Timer timer){ String message = (String)timer.getInfo(); //do some work } } COMMUNITY Java EE 6とともにリリースされたJava Servlet 3.0仕様では、非同期処理がサポー トされています。HTTPクライアントの観点か らは、非同期のサーブレット要求と「従来型の」 サーブレット要求の間に違いはありません。非 同期型と従来型のいずれの場合でも、クライア ントは要求が完了するまでブロックされます。 非同期要求を使用した場合、Webコンテナ において、スレッドをバインドすることなくブラ ウザからの接続をブロックできます。service メソッドはただちに制御を返しますが、その 後もAsyncContextインスタンスを使用 して、ブラウザやその他のHTTPクライアント (JAX-RSクライアントなど)にメッセージを 送り返すことができます(リスト3参照)。 非同期要求を実現するためには、 サ ー ブ レ ット と そ の 呼 び 出 し チ ェ ー ン に 含 ま れ る す べ て の フィル タ を 、 a s y n c S u p p o r t e d = t r u e オプション を指 定してデプロイする必 要 が あります 。 HttpServletRequest#startAsync() メソッドによって、要求が非同期モードになり、 AsyncContextインスタンスがただちに返 されます。この動作は、@Asynchronous を付加したメソッドがFutureインスタンスを 返す動作と似ています。AsyncContextイ ンスタンスは実質的にブラウザ・ウィンドウ(ま たはHTTPクライアント)を表しており、これ を利用することで、serviceメソッド(および doGet、doPostなど)の完了後にクライアン トと通信できます。 リ スト 3 で は 、A s y n c S e r v l e t は AsyncContextをCDIイベントとして送信し ています。このAsyncContextは、Singleton のEJB BeanであるEventBroker(リスト4 参照)が受け取ります。 A s y n c C o n t e x t は 、今 後 の 通 知 処 理 の た め 、ロ ッ ク の 発 生 し な い CopyOnWriteArrayList contexts型 のcontextsインスタンスに格納されます。 リスト4 ABOUT US すべて、キューに格納され、アプリケーション・ サーバーが管理するスレッドによって実行され ます。このタスク・キューは一時的なデータ構 造であり、アプリケーション・サーバーがクラッ シュした場合、送信されている未処理のタスク はすべて消失します。 タスク・キュー が 一 時 的 なもの で あるた め、@Asynchronousを付加したメソッド を、JMSの永続キューを使用して実装された Service Activatorパターンの代替手段とし て使用することはできません。 一時的なスレッド・キューを利用できない場 合は、永続的なシングル・アクション・タイマー を使用して非同期呼び出しを実現できます。リ スト2に示すように、まず、クライアントに公開 するexecuteAsyncメソッドの中で永続的 なシングル・アクション・タイマーを作成する必 要があります。 タ イ マ ー に は パ ラ メ ー タとして Serializableインスタンスを渡すこともで きます。タイマーに渡すパラメータはすべて、 Serializable型のホルダーでラップする必要 があります。タイマーは永続オブジェクトとして 設定されるため、アプリケーション・サーバーで は、タイマーを実行する前に情報の呼び出し元 のトランザクションを永続化する必要がありま す。@Asynchronousを付加したメソッドで は、このようなオーバーヘッドが必要ありませ ん。そのため、パフォーマンスが改善されます。 な お 、E J B 3 . 1 仕 様 で は 、@ Asynchronousが付加されたメソッドに対 するオーバーロードは定義されていません。 同時実行要求の最大数は規定されておらず、 したがってスレッド数の最大値も規定されて いません。ほとんどのアプリケーション・サー バーで、@Asynchronousが付加されたメ ソッドの実行のみを目的としたスレッド・プール を独自の方法で設定できます。 リスト3 JAVA IN ACTION リスト2 JAVA TECH //enterprise java / 全てのリストをテキストで表示 EventBroker#onNewEventメソッド は、呼び出されるたびに、contextsリストに 格納されているすべてのAsyncContext インス タンスに 対して 反 復 処 理 を 実 行し ます。String型のmessageパラメータ を渡し、AsyncContext#complete メソッドによって 要 求をコミットし、最 後に AsyncContextをリストから削除します。 このonNewEventメソッドは、実質的に は、呼び出されるたびにString型のmessageパラメータをすべてのリスンしている HTTPクライアントに配信します。onNew- Eventメソッドの呼び出しでは、クライアント にメッセージが到着するまでブロックが実行さ れます。これは典型的なファイア・アンド・フォー ゲット型の呼び出し方法であるため、メソッドに @Asynchronousアノテーションを付加す ることによって、容易に呼び出しをバックグラウ ンドで実行できます。本記事のサンプル・アプリ ケーションでは、JAX-RSリソースでString 型のmessageイベントを配信(fire) してい ます(リスト5参照)。 ビジネス層のEJB BeanにHTTP APIを 直接公開し、AsyncContextを中立的な 55 JCA̶詳細な制御のために Java EE Connector Architecture(JCA) 1.6コネクタを使用した場合、並行処理を、便 利で監視可能な「正規の」方法で完全に制御 できます。さらに、JCAコネクタはアプリケー ション・サーバーによって管理されるため、通常 は、さまざまな設定オプションを利用できます。 JCA 1.6コネクタの作成は、単純ではないも のの、数時間で完了できます。 ResourceAdapterの実装で は 、オ ー バ ー ラ イドし た s t a r t メソッド BootstrapContextを受け取ります。 これ により、W o r k M a n a g e r インスタ ン ス に ア ク セ ス で き る ように な りま す 。 ResourceAdapterインタフェースに定義 されているその他のメソッドは、すべて無視し てかまいません(リスト7参照)。 必要な作業は、リスト7に示すクラスをコン パイルした後、そのクラスをJARファイルに格 納し、ファイルの拡張子を.jarから.rarに変更 して、コネクタをデプロイすることだけです。 これにより、アプリケーション・サーバーによっ てWorkManagerBootstrapコネクタが 作成され、BootstrapContextが渡されま す。このBootstrapContextを使用して、 WorkManagerインスタンスを取得できます。 WorkManagerによって、Runnableイ ンタフェースを継承したjavax.resource. spi.work.Workインスタンスを実行できま す。この解決策で目的は果たせますが、アプリ ケーションでWorkManagerへの参照を取 得できるようにする場合は、変則的な作業が 必要です。ただし、管理しやすいネットワーク・ ORACLE.COM/JAVAMAGAZINE ////////// JULY/AUGUST 2012 リスト8b public class BrowserWindow { private AsyncContext asyncContext; private final ServletResponse response; private String channel; public BrowserWindow(AsyncContext asyncContext) { this.asyncContext = asyncContext; this.response = this.asyncContext.getResponse(); this.response.setContentType("application/xml"); } public BrowserWindow(AsyncContext asyncContext,String channel){ this(asyncContext); this.channel = channel; } public void send(){ try{ this.asyncContext.complete(); }catch(Exception e){ } } public Writer getWriter(){ try { return this.asyncContext.getResponse().getWriter(); } catch (IOException ex) { throw new IllegalStateException("Cannot return writer: " + ex,ex); } } COMMUNITY サーバーを導入するためには、この解決策で 十分です。 J C Aコネクタ の 動 作 方 式 はコネクショ ン 型 で す 。そ の た め 、少 なくとも j a v a x . resource.spi.ManagedConnection とj a v a x . r e s o u r c e . s p i . M a n a g e d C o n n e c t i o n F a c t o r y の 2つのインタ フェースを実装する必要があります。いずれの インタフェースも、1度実装するだけで複数の JCAコネクタ実装で再利用できます。 C o n n e c t i o n F a c t o r y クラ ス(リ スト 8 a お よ び リ スト 8 b 参 照 )で は 、@ ConnectionDefinitionアノテーションを 使用して、メタデータをランタイムに公開して います。この@ConnectionDefinitionア ノテーションとWorkManagerBoostrap の@Connectorアノテーション(リスト7参 照)を使用することで、Resource Adapter Archive(RAR)のXMLデプロイメント・ディス クリプタが不要になります。 W o r k M a n a g e r B o o t s t r a p は、コ ネクタのデプロイ時に1 度だけインスタン ス 化 さ れるため 、実 質 的には S i n g l e t o n で す 。C o n n e c t i o n F a c t o r y で は 、 WorkManagerBootstrapの内部に WorkManagerインスタンスが格納されて いる必要があります。 J C A 1 . 6 S P I に は 、j a v a x . resource.spi.Resource A d a p t e r A s s o c i a t i o n と いう有 用 な イ ン タ フェー ス が 含 ま れ て い ま す 。こ の イ ン タ フェ ー ス を コ ン テ ナ で 使 用 す ることにより、R e s o u r c e A d a p t e r の 実 装( W o r k M a n a g e r B o o t s t r a p ) とM a n a g e d C o n n e c t i o n F a c t o r y の 実 装 を 関 連 付 け ること が で き ま す 。R e s o u r c e A d a p t e r を WorkManagerBootstrapにキャストする ことによって、ConnectionFactoryが、非 同期実行に必要となるWorkManagerイン リスト8a JAVA IN ACTION ラッパーでラップするという手法は、通常は好 ましくありません。オープンソース・プロジェ クトのLightFishでは、BrowserWindow クラスを使用して、JavaFX 2クライアント にGlassFishの監視データを送信しています (リスト6参照)。 リスト7 JAVA TECH リスト6 ABOUT US //enterprise java / public void nothingToSay(){ HttpServletResponse httpServletResponse = (HttpServletResponse) response; httpServletResponse.setStatus(204); this.asyncContext.complete(); } } public String getChannel() { return channel; } 全てのリストをテキストで表示 56 ORACLE.COM/JAVAMAGAZINE ////////// JULY/AUGUST 2012 リスト10 リスト11 public class Connection implements ManagedConnection { private private private private private ConnectionFactory mcf; PrintWriter out; JCAExecutor fileConnection; ConnectionRequestInfo connectionRequestInfo; List<ConnectionEventListener> listeners; Connection(PrintWriter out,ConnectionFactory mcf, ConnectionRequestInfo connectionRequestInfo) { this.out = out; this.mcf = mcf; this.connectionRequestInfo = connectionRequestInfo; this.listeners = new LinkedList<ConnectionEventListener>(); } public Object getConnection(Subject subject, ConnectionRequestInfo connectionRequestInfo) throws ResourceException { fileConnection = new JCAExecutor(out,this,mcf, connectionRequestInfo); return fileConnection; } public void destroy() { this.fileConnection.destroy(); } COMMUNITY リスト9c JAVA IN ACTION スタンスにアクセスできるようにな ソッドにRunnableインスタンス さらなる改善 ります。 を渡すことで、そのインスタンスが Java EE 7で ConnectionFactoryは、接続 WorkManagerによって非同期的 の適切な管理とプーリングに必要な に実行されます(リスト10参照)。 は 、並 行 処 理 機構に過ぎません。そのため、setjava.util.concurrent. に 関 す る さら MaxNumberOfConcurrentExecutorインタフェースを実装 に 興 味 深 い 機 Requestsメソッドによって、アプリ するJCAExecutorは、アプリ 能 が 利 用 で き ケーション・サーバーの管理および設 ケーションによって直接使用され、 定機構に対して書込み可能なプロパ JCAExecutorFactoryによっ る予定です。 ティを公開しています。すでに作成 て作成されます(リスト11参照)。 済みのManagedConnectionイ J C A E x e c u t o r ンスタンスをプーリングするために お よ び そ れ に 対 応 す る は、matchManagedConnectionsメソッ J C A E x e c u t o r F a c t o r y は 、実 際 ドの実装が必要です。 の ド メ イ ン に 依 存 す る 実 装 で す 。一 接続の識別には、通常、ユーザー名やパス 方 、M a n a g e d C o n n e c t i o n お よ び ワードなどのセキュリティ認証情報を使用し ManagedConnectionFactoryの実装 ます。しかし、本アプリケーションではすべて は、ほとんどの場合ビジネス・ロジックに依存 のスレッド・プールが同一であるため、単純に せず、他のJCA実装で再利用できます。すべ ConnectionRequestInfoインスタンスを てのクラスは、拡張子が.rarのJARファイルに 使用して接続を特定します。 パッケージ化し、アプリケーション・サーバーに ManagedConnectionの実装 デプロイする必要があります。 (Connection) とManagedConnection Java EEアプリケーションでは、JCAの実 Factoryの実装(ConnectionFactory) 装について意識する必要はなく、管理下の環 のいずれも、接続管理を論理レベルで実現 境においてタスクを非同期的に実行すること するため、容易に再利用できます。さらに、 のみに注意を払うことができます。アプリケー Connectionクラス(リスト9a、 リスト9b、 リ ションから操作するAPIは、アプリケーションに スト9c参照)では、アプリケーション・サーバー Executorを返す1つのインタフェースのみ のランタイムに対して現在の状態を通知する です(リスト12参照)。 イベントを配信します。 これにより、Java EE 6のアプリケーション Connectionインスタンスは、 が、Java SE環境と同じように容易に、管理さ ConnectionEventListenersのリストを れたExecutor実装にアクセスできるように 管理し、切断、コミット、開始、ロールバックの各 なりました(リスト13参照)。 イベントを配信します。本アプリケーションのコ Java EE 7̶さらなる改善 ネクタの実装は、 トランザクション型ではないた 5つのクラスと1つの単純なMaven Project め(トランザクション型にするような実装も可能 Object Modelを作成することによって、 です)、ほとんどのイベントが配信されません。 Connectionは論理レベルですが、物理レ XMLデプロイメント・ディスクリプタを使用せ ベルの管理も行います。Connectionコネク ずに、スレッド・プールの柔軟な実装を実現で タの「実体」にあたるものがJCAExecutor きます。この実装は、アプリケーション・サー です。JCAExecutorでは、executeメ バーによって完全に管理され、 トランザクショ リスト9b JAVA TECH リスト9a ABOUT US //enterprise java / public void cleanup() { } public void associateConnection(Object connection) { this.fileConnection = (JCAExecutor) connection; } 全てのリストをテキストで表示 57 リスト13 import java.io.Serializable; import java.util.concurrent.Executor; import javax.resource.Referenceable; ABOUT US JAVA TECH public interface WorkExecutorFactory extends Serializable, Referenceable { Executor newExecutor(); } JAVA IN ACTION リスト12 COMMUNITY //enterprise java / 全てのリストをテキストで表示 ン、セキュリティ、進行状況の監視をサポート するように拡張することができます。 Java EE 7では、並行処理に関するさ らに興味深い機能が利用できる予定です。 JMS 2.0では、メッセージ送受信のプロセス が大幅に単純化されます。EJB 3.2では、@ MaxConcurrencyなど、QoSに関する追 加機能がサポートされる見込みです。おそら く、Java EE 7には、並行処理を主題とした仕 様が含まれることになるでしょう。 アプリケーションでスレッドを管理する場 合、そのスレッドはアプリケーション・サーバー のランタイムから見えません。そのため、同時 実行数の制限やアプリケーションの動作の監 視が不可能です。手動でスレッドを作成すれ ば、スケーラビリティが損なわれるだけでなく、 システム全体の堅牢性が大きな影響を受けま す。アプリケーションでクラウドに対応する必 要性が高まるほど、希少なリソースの一元管理 が重要になり、それゆえスレッドがますます重 要になります。</article> LEARN MORE • connectorZ • 『Real World Java EE Night Hacks̶ Dissecting the Business Tier』70ページ (press.adam-bien.com、2011) ORACLE.COM/JAVAMAGAZINE ////////// JULY/AUGUST 2012 58