Java SE 8ͷ Java EE 7ΞϓϦέʔγϣϯ։ Yoshio Terada Java Evangelist http://yoshio3.com Twitter : @yoshioterada #jdt2014_C1
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 1
Java SE 8時代の Java EE 7アプリケーション開発
Yoshio Terada Java Evangelist http://yoshio3.com Twitter : @yoshioterada #jdt2014_C1
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 2
以下の事項は、弊社の一般的な製品の方向性に関する概要を説明するものです。また、情報提供を唯一の目的とするものであり、いかなる契約にも組み込むことはできません。以下の事項は、マテリアルやコード、機能を提供することをコミットメント(確約)するものではないため、購買決定を行う際の判断材料になさらないで下さい。オラクル製品に関して記載されている機能の開発、リリースおよび時期については、弊社の裁量により決定されます。
Oracleは、米国オラクルコーポレーション及びその子会社、関連会社の米国及びその他の国における登録商標です。文中の社名、商品名等は各社の商標または登録商標である場合があります。
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 3
今日のアジェンダ 1. はじめに 2. Java 8 の世界 3. Java SE 8 + EE 7 Concurrency Utilities
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 4
今日のアジェンダ 1. はじめに 2. Java 8 の世界 3. Java SE 8 + Concurrency Utilities
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 5
祝 Java SE 8 正式リリース 2014 年 03 月 18 日
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 6
Java SE 8 2014年03月18日
Java SE 8 新機能
Lambda 式 & Stream API JavaFX JavaScript Engine Compact Profile Date & Time API Type Annotation
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 7
今日は 2つのメッセージを お届けします
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 8
今日のアジェンダ 1. はじめに 2. Java 8 の世界 3. Java SE 8 + EE 7 Concurrency Utilities
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 9
今後 10 年 500億のデバイス
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 10
全てが繋がる 時代へ !!
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 11
Java SE 8 Compact プロファイル
各APIにどのプロファイルで 利用可能か記載されている
参考:https://blogs.oracle.com/jtc/entry/a_first_look_at_compact
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 12
デモ
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 13
これで終わり?! 基調講演でやったよね?
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 14
Java EE 7は ?!
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 15
LEGO(Java SE Embedded) & Java EE 7 WebSocket デモの構成
GlassFish v4.0.1 Java SE8/EE 7 Java SE8
Embedded
LEGO MindStorms の操作命令を送信
LEGO MindStorms の状態情報を送信
WebSocket LEGO
エンドポイント
WebSocket サーバ
エンドポイント
WebSocket ブラウザ
エンドポイント
JSON
JSON
JSON
JSON
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 16
ブラウザからLEGOマインドストームを操作 WebSocket でリアムタイム IoT 通信
ブラウザからの命令 前後左右への移動 停止、スピードアップ・ダウン LEGO からの情報 超音波センサー・データの表示 JSON でデータ送受信し RMI に比べ低オーバヘッド
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 17
Java SE 8/EE 7 だけで実現
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 18
今後 10 年も Java !!
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 19
今日のアジェンダ 1. はじめに 2. Java 8 + WebSocket 3. Java SE 8 + EE 7 Concurrency Utilities
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 20
より応答の速い サービスは必要ですか?
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 21
Application Servers
Java SE
Web/EJB コンテナ
EJB JSP
Servlet
Runnable
Callable
Java EE 7 で追加されたサーバ・サイドの並列処理 Concurrency Utilities for EE
Java EE 関連機能 (JAX-RS,JavaMail, CDI など)
ManagedExecutor Service ManagedScheduledExecutorService ContextService ManagedThreadFactory
Concurrency Utilities for EE
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 22 Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 22
さて、ここで質問
(これは Java EE ではなく Java SE の質問)
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 23
Java SE 8 時代どこがおかしい?
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 24
Lambda 式に修正したしこれで OK?
そう!!Lambda 式の適用
(() -> 1);
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 25 Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 25
Java SE 8 (Lambda式) 対応も実施 もう問題ない?!
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 26
本当に?!
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 27 Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 27
これだけだと課題は分からない もう少し複雑な課題で確認しましょう。
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 28
10個の並列処理タスクを実行し、 その結果、終わった順番に取得して表示ください。
課題
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 29
1. 固定長のスレッドプールを持つ、ExecutorService を作成する
2. ExecutorCompletionService を使用する 3. 結果を格納するリストを作成する 4. Callableを実装した10 個の並列タスクを実行する 5. 実行結果を取得する
10 個の並列タスク実行の実装方針例
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 30
1. 2. 3. の実装 : 今まで同様の実装
// 1. 固定長スレッドプールを持つ ExecutorService の作成 ExecutorService exec = Executors.newFixedThreadPool(10);! // 2. 並列処理を実行する際、処理が完了した順に結果を取り出すサービス ExecutorCompletionService<Integer> execCompService! = new ExecutorCompletionService<>(exec);! // 3. 処理結果を格納するリスト List<Future<Integer>> futures = new ArrayList<>();
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 31
4. タスクの実装 : MyCallable タスクの実装
public class MyCallableTaskImpl implements Callable<Integer> {! private final int counter;! public MyCallableTask(int counter) {! this.counter = counter;! }! @Override! public Integer call() throws Exception {! int randomValue = (int) (Math.random() * 10000);! try {! Thread.sleep(randomValue);! return counter;! } catch (InterruptedException ex) {! logger.log(Level.SEVERE, null, ex);! return -1;! }! }}
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 32
4. 並列タスクの実装と実行
// 並列処理タスクを 10 個作成し実行 for (int i = 0; i < 10; i++) {! // 並列タスクを別途 MyCallableTask クラスに実装 MyCallableTaskImpl task = new MyCallableTaskImpl(i);! //タスクを実行し、実行結果をリストに追加 futures.add(execCompService.submit(task)); }
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 33
これからは Java SE 8の時代
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 34
// 並列処理タスクを 10 個作成し実行 IntStream.range(0, 10).forEach(i -> {! futures.add(execCompService.submit(() -> {! int randomValue = (int) (Math.random() * 10000);! Thread.sleep(randomValue);! return i;! }));!});
Lambda & Stream でスッキリ
4. 並列タスクの実装と実行 Java SE 8
for 文はもう書かない CallableをLambdaで実装
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 35
5. 実行結果の取得
// 並列処理タスクを 10 個作成し実行 for (Future<Integer> results : futures) {! try {! // 処理結果順に結果を取得 Integer result = execCompService.take().get();! System.out.println(result);! } catch (InterruptedException | ExecutionException ex) {! // 例外処理の実装 }!}
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 36
これからは Java SE 8の時代
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 37
5. 実行結果の取得
futures.stream()! .mapToInt(future -> {! try {! return execCompService.take().get();! } catch (InterruptedException|ExecutionException ex) {! return -1;! }! })! .forEach(System.out::println);
Java SE 8
Lambda & Stream でスッキリ
Collection 操作はStream API
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 38
プログラムの実行 10個のタスクの内、完了順にタスク番号を表示
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 39 Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 39
Java SE 8 対応も実施 もう問題ない?!
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 40
本当に?!
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 41 Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 41
キーワードは Blocking
Future#get() で処理をブロック
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 42
後続処理を ブロック
LinkedBlockingQueue
メイン・スレッドの実行
1
2
3
10
並列タスク(作成順)
処理時間 : 9秒
処理時間 : 1秒
処理時間 : 5秒
処理時間 : 2秒
2 10 ・・ 3 1
n
「後続処理をブロック」 が大きな課題
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 43
ブロック
全てのタスクの結果を受け取るまで 後続の処理を実行する事は不可能
ブロック
ブロック
処理時間 : 9秒 1
並列処理 n
並列処理 n
パフォーマンス・応答時間に影響
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 44 Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 44
Java SE 8 から Future, Callable は古い !!
for 文 禁止令と同様 Callable 禁止
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 45 Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 45
CompletableFuture を使いましょう
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 46 Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 46
CompletableFuture はJava EE 環境でも利用可能
用途に応じて応答速度が大幅改善
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 47
デモ
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 48
CompletableFuture 59 個のメソッド
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 49
CompletableFuture#supplyAsync()
supplyAsync() は開始ポイントの一つ java.util.stream.Stream のように実装可能
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 50
CompletableFuture による ノン・ブロッキングの並列処理 (パイプライン処理)
並列処理の実行
supplyAsync!runAsync
結果を取得し 次の処理を実行
thenAccept!thenApply!themCompose!thenRun
結果を取得し (最終)処理を実行
complete!cancel!isCompletedExceptionally!
exceptionally!get!getNow!whenComplete!など
ノン・ブロッキング
他の処理を実行可能
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 51
2 結果を取得し 別の処理を実行可能 CompletableFuture A
CompletableFuture B A.acceptEither(B,**)!A.acceptBoth(B,**)!A.applyToEither(B,**)!A.runAfterBoth(B,**)!A.runAfterEither(B,**)!A.thenAcceptBoth(B,**)!A.thenCombine(B,**)!
CompletableFuture による 2 つの並列処理の実行結果より新たな処理を実行
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 52
各機能ごとに3種類づつ用意
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 53 Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 53
ご注意: Java EE 環境で ForkJoin を使用する API の使用は非推奨
ExecutorService を指定可能な メソッドを利用しましょう。
例:CompletableFuture は ExecutorService を利用可能 supplyAsync(Supplier<U> supplier, Executor executor) thenAcceptAsync(Consumer<? super T> action, Executor executor)
Java EE 7
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 54 Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 54
CompletableFuture<T> tasks = ! CompletableFuture! .supplyAsync(Supplier <U> supplier))! .thenAcceptAsync(Consumer<? super T> action)!
Stream 操作に類似したパイプライン処理 # Stream#filter().map().forEach(); メソッドの実行結果、新たな CompletableFuture を返す
CompletableFuture を使用した実装例 Java SE 8
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 55
CompletableFuture<T> tasks = CompletableFuture! .supplyAsync(Supplier <U> supplier))! .thenAcceptAsync(Consumer<? super T> action)!
• supplyAsync() は Supplier を引数に持つ • Supplier は java.util.function パッケージに 含まれる関数型インタフェース • Lambda 式で記述可能
supplyAsync() の実装について
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 56
final int data = i;!Supplier<Integer> func = new Supplier<>() {! @Override! public Integer get() {! int randomValue = (int) (Math.random() * 2000);! mystopThread(randomValue);! return i;! }!};!
Lambda 式をいきなり書けない方
インナー・クラスとして実装して考えてみましょう Supplier は引数が無しの何か値を返す関数だと理解可能 処理を実装した後、結果を返す
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 57
final int data = i;!Supplier<Integer> func = new Supplier<>() {! @Override! public Integer get() -> {! int randomValue = (int) (Math.random() * 2000);! mystopThread(randomValue);! return i;! }!};!
Lambda 式におきかえる
メソッドの引数と、メソッドボディ部分以外を削除 引数部分とメソッド・ボディの間に矢印(->)を挿入
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 58 Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 58
final int data = i;!CompletableFuture<T> tasks = CompletableFuture! .supplyAsync(() -> {! int randomValue = (int) (Math.random() * 2000);! mystopThread(randomValue);! return data;! })! .thenAcceptAsync(Consumer<? super T> action)!
CompletableFuture の実装を修正
Supplier の内容を supplyAsync() メソッドの引数に記述
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 59
thenAcceptAsync() の実装について final int data = i;!CompletableFuture<T> tasks = CompletableFuture! .supplyAsync(() -> {! int randomValue = (int) (Math.random() * 2000);! mystopThread(randomValue);! return data;! })! .thenAcceptAsync(Consumer<? super T> action)!
• thenAcceptAsync() は Consumer を引数に持つ • Consumer は java.util.function パッケージに含まれる関数型インタフェース • Lambda 式で記述可能
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 60
Consumer<Integer> consume = new Consumer<Integer>() {! @Override! public void accept(Integer result) {! System.out.println(result);! }!};!return consume;!
Lambda 式をいきなり書けない方
インナー・クラスで実装して考えてみましょう
Consumer は引数が一つで何も値を返さない関数だと理解可能 引数で取得した値を元に、別処理を実装
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 61
Consumer<Integer> consume = new Consumer<Integer>() {! @Override! public void accept(Integer result) -> {! System.out.println(result);! }!};!return consume;!
Consumer<Integer> consume = (result) -> {! System.out.println(result); }};!return consume;! 型定義などを省略 Consumer<Integer> consume = System.out::println;!return consume;! メソッド参照による実装
Lambda 式に置き換える
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 62 Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 62
final int data = i;!CompletableFuture<T> tasks = CompletableFuture! .supplyAsync(() -> {! int randomValue = (int) (Math.random() * 2000);! mystopThread(randomValue);! return data;! })! .thenAcceptAsync(System.out::println)!
CompletableFuture を使用した実装結果
並列処理もノン・ブロッキング実装で より応答時間を高める事ができます
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 63
CompletableFuture 是非ご活用ください
クライアント・サイドの実装では 利用場面は少ないかもしれません。 サーバ・サイドは用途に応じて有用です。 Java EE 7 環境でも利用可能です。 (ManagedExecutorService) 複雑な並列処理が必要な場合は、 是非、ご活用ください。
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 64 Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 64
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 65
Graphic Section Divider
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. 66