EE(JSR-236)の歴史や実装方法、ポイント、注意点などについて解説した。SE環境におけるスレッド処理の実装などの変遷を振り返った。Utilitiesを導入。これにより、並列処理やスレッド・プーリング、キューイングなどが簡単に実装できるようになった。7ではFork/Joinに対応。8ではラムダ式をサポートし、これまで以上に並列処理が簡単に記述できるようになるという。このように、Javaにおける非同期処理の仕組みは着々と進化を続けているが、残念ながら開発の現場では、まだこれらの機能が十分に活用されていないと寺田氏は嘆く。書いているプログラムを多く見かけるが、もうこのような実装はやめたほうがよい」とアドバイスした。スレッドを無限に生成するこのコードでは、スレッドを生成する度にスタック領域が確保されてメモリを消費するほか、コンテキスト・スイッチも発生するため、パフォーマンスは決して良くならない。スレッド生成は処理コストが高く、こうした方法ではマルチコア・プロセッサ環境でその性能を十分に発揮できないのだという。Utilitiesである。Utilitiesは並列処理の実装を簡素化するために導入されたAPIで、これを利用することによってスレッドのライフサイクル管理が簡単になるほか、スケーラビリティやパフォーマンスが大幅に向上するのだという。導入により、パフォーマンスはどのくらい変わるのだろうか。Utilitiesを使用してそれぞれどの程度パフォーマンスが変わるのかをグラフィカルに確認することのできるデモを披露した。Utilitiesを使った場合は256個のプロセッサの負荷がほぼ同時に限界まで達し、瞬時に処理を終えることが確認できた。「Javaはパフォーマンスが悪いという声を聞くことがあるが、それは間違い。パフォーマンスが悪いのは、いまだに古いやり方でプログラムを書いているからにすぎない。EJB」について説明した。JMSとMDBを使用すると、アプリケーション・サーバ管理者が事前にMQ用の接続を設定しておくことで、その設定情報をプログラマーがインジェクト(注入)してMQのプロバイダにアクセスするといったプログラミングが可能になる。7にバージョンアップすることで「これまで以上に楽になる」と寺田氏は話す。true」というアノテーションを付加することで非同期処理が行えるようになった。Object)に「@Stateless」というアノテーションを付加し、メソッドに「@Asynchronous」というアノテーションを付加すれば非同期で動作させられるという。}}ただし、「このように簡単に実装できるようになるものの、これは単なる非同期処理であって、並列(Concurrency)処理ではないことを忘れないでほしい」と寺田氏は注意を促す。ここで氏は、同期処理と非同期処理の違い、そして並列処理と非同期処理の違いを説明した。同期処理と非同期処理の違いの説明で寺田氏が用いたのは、iPhoneにメール・メッセージを送るEJBアプリケーションのデモである。このデモで同期処理の場合には、メッセージの送信命令を実行した後にメール送信が完了するまで待ち続けることになる。その間、ユーザーにレスポンスを返すことはなく、結果として、ユーザーは処理が完了するまで画面を操作できなくなる。ユーザーはすぐに画面操作が行える。このとき、アプリケーションは非同期でメール送信の処理を行っている。それでは、非同期処理と並列処理はどう違うのだろうか。寺田氏は、複数の旅行代理店に対してホテルの空室状況や飛行機の空席情報を検索するシステムを想定し、各旅行代理店に並列で検索要求を出し、検索が完了した順に結果を一覧表示するデモ・アプリケーションを披露した。7の新機能の1つであるWebSocket(JSR-356)の技術を組み合わせて実装されている。Contextを生成して“単一の”非同期タスクを実行する。この非同期実行されるタスクでは、複数の旅行代理店に問い合わせを行う場合でも、それぞれの旅行代理店に対して順番に問い合わせる必要がある。6では非同期で処理は行えるが、非同期処理の実装で並列処理(新たなスレッドの生成)をサポートしていないため、タスクの実装では複数の旅行代理店に対して順番に問い合わせざるをえなかったのだ。並列処理では、上のような非同期処理を1つだけ実行するのではなく、複数のタスクを並列に同時実行することができる。したがって、複数の旅行代理店がある場合は、それぞれに対して一斉に並行して問い合わせることが可能となる。実際にデモの画面では、各旅行代理店から検索結果が返ってきた順に結果が表示された。6までは、EJBコンポーネントやサーブレットの中から新しいスレッドを生成することは仕様として禁止されていた。新しいスレッドを作った場合、同じJVM上でスレッドが作られるものの、アプリケーション・サーバが管理するスレッドとは別のスレッドとして生成されるため、アプリケーション・サーバからそのスレッドを管理する手段がなかったのだ」(寺田氏)したがって、新たに作ったタスクに対してコンテキスト情報やクラス・ローダ、セキュリティなどの情報を渡すことができず、さらに生成されたタスクからアプリケーション・サーバのリソースを呼び出すこともできなかった。加えて、「アプリケーション・サーバが停止、またはアプリケーションが無効化された場合でも、ライフサイクルが異なるために生成されたタスクは処理を続行してしまうといった管理不能の状態に陥る可能性もあった」(寺田氏)。EEでは、APIを介してアプリケーション・サーバ内でタスク管理が行えるようになるのだ。Utilitiesが使えるようになるわけだが、「その使用に際しては、まずパッケージjavax.enterprise.concurrentに含まれる次の4つのインタフェースの特徴を押さえておいてほしい」と寺田氏は説明する。(1)インタフェースManagedExecutorService(2)インタフェースManagedScheduledExecutorService(3)インタフェースContextSerivce(4)インタフェースThreadFactoryこれらのうち、(1)と(2)は非常に簡単に非同期のタスクを利用できるインタフェースであり、(3)、(4)は使い方が少し難しいが、自分で並列処理をコントロールしたい場合に利用するインタフェースである。簡単に並列処理を利用できるのは、(1)のインタフェースManagedExecutorServiceだ。このインタフェースを使う場合には、まずインタフェースRunnableかCallableをimplementsしたタスクを作成する。}}続いて、サーバ側の設定を行う(デフォルト設定でも可)。最後に、作成したタスクに対して「managedExecsvc.submit(task);」といったコードを実装するだけでよい。TimeUnit.SECONDS);」」といったコードを実装するだけで、タスクのスケジューリング(ここでは1分後にタスクを実行)が可能になる。}上のコードは時間を指定してタスクを実行する場合の例だが、独自のトリガを指定することも可能であり、どのようなときにタスクを実行するのか、あるいはスキップするのかをプログラム側でコントロールすることもできる。EEの本質を理解するためには、以降で紹介する(3)、(4)の方法を理解することが重要だと寺田氏は語る。Utilitiesの肝になる部分」(寺田氏)である。EE環境上で動作させるために必要なコンテキスト情報などを付加して実行する。SEで提供されるインタフェースExecutorServiceを利用することも可能になる。(もしくはThreadPoolExecutorのユーティリティ・クラスであるExecutors)を使って独自のスレッド・プールを定義し、そこから新たなスレッドを生成することも可能だという。Injection)では使用に制限がある」といったことが挙げられる。7を使い非同期マルチタスクを並列に実行することで、計算機資源をより有効に活用できるようになる。EE環境で簡単かつ安心してスレッド生成が行えるようになり、柔軟性も非常に高いので、ぜひ皆さんもこの機能をフルに活用していただきたい」と呼びかけて講演を締めくくった。お試しいただけるトライアル・サービスをご提供しております。permission.×このサイトでは、利用状況の把握や広告配信などのために、Cookieなどを使用してアクセスデータを取得・利用しています。これ以降ページを遷移した場合、Cookieなどの設定や使用に同意したことになります。Cookieなどの設定や使用の詳細、オプトアウトについては詳細をご覧ください。