Java SE 8時代の Java EE 7アプリケーション開発...LEGO(Java SE Embedded) & Java EE 7...

Preview:

Citation preview

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

Recommended