Javaの並列処理いろいろ

こんにちは。サイオステクノロジー技術部の武井です。最近Azure Service Fabricのことを色々調べています。C#ではなくて、Javaの実装で調べているのですが、その中でFutureComletableっていうのが出てきました。どうやら、Java8から実装された並列処理みたいなのですが、色々調べているうちにJavaの並列処理はいろんな変遷をたどっているんだなーということがわかり、ここにまとめておきました。

Runnable

古き良きRunableの実装です。Runnableインターフェースを実装したクラスで、runメッソドをオーバーライドして実行します。

実行結果はこんな感じです。

メインの処理だん
スレッドの処理開始

「メインの処理だん」が先に表示されるので、ちゃんと並行処理出来ています。

Executor

多分、Runnableの次に出てきた実装だと思います。スレッド処理の結果を簡単に取得出来ます。Executorが出る前は、Runnableでこんなことしてました。

実行結果はこんな感じです。

スレッドの処理開始
スレッドの処理だん
メインの処理だん
スレッドの処理の結果:結果が出ました

上記の処理をExecutorで行うと、こんなにもシンプルになります。

おお(`・ω・´)シャキーン
すごい。

私が知っていたのは、ここまででした。

Function、Supplier、Consumer、BiConsumer

FutureCompletableの説明をする前にFunction、Supplier、Consumerという概念が必要なので、下記に説明します。これらは、メソッドをインスタンスの様に扱うことが出来ます。

Function
引数を取り、戻り値も必要なメソッドをインスタンス化するのに使います。

String function(String value) {
return value;
}

これを以下のように表します。

Function<String, String> function = new Function<String, String>() {
@Override
public String apply(String t) {
return t;
}
};

ラムダ式で書くと、以下になります。

Function<String, String> function = (t) -> t;

実行するのは以下です。

function.apply("hoge");

Supplier
引数を取らないが、戻り値を返すメソッドをインスタンス化するのに使います。

Supplier<String> supplier = new Supplier() {
@Override
public String get() {
return "hoge";
}
};

ラムダ式で書くなら、以下になります。

Supplier<String> supplier = () -> "hoge";

Consumer
引数を取るが、戻り値を返さないメソッドをインスタンス化するのに使います。

Consumer<String> consumer = new Consumer() {
@Override
public void accept(String t) {
System.out.println(t);
}
};

ラムダ式で書くなら、以下になります。

Consumer<String> consumer = t -> System.out.println(t);

BiConsumer
引数を2つ取るが、戻り値を返さないメソッドをインスタンス化するのに使います。

BiConsumer<String> biConsumer = new BiConsumer() {
@Override
public void accept(String t,String u) {
System.out.println(t + u);
}
};

ラムダ式で書くなら、以下になります。

BiConsumer<String> consumer = (t,u) -> System.out.println(t + u);

FutureCompletable

Java8から出てきた並列処理の実装です。とってもたくさんのことが出来ます。基本的にはRunnableやExecutorの様にスレッドによる並行処理を行うのですが、色々な便利機能があるのです。その便利機能のうち、4つの実装例を以下に記載します。

まず、一番単純な処理から。スレッドを実行して、その戻り値を表示します。

次に、戻り値が固定で決まっているときのケースです。

1つ目の処理の結果を受け取って、2つ目の処理を行います。この例では、1つ目の処理では、noriyukiという文字列を返し、2つ目の処理がその文字列を受け取って、「Hello!!」という文字列をくっつけてます。つまり結果は、「Hello!! noriyuki」となります。こんなことも簡単にできるんです(`・ω・´)シャキーン

全てのスレッドの実行の結果を待って、一気に戻り値を返します。

最後に

いかがでしょうか?あまり、メジャーでないFutureCompletableですが、使い所によっては強力な武器になりそうな気がします((o(´∀`)o))ワクワク

ご覧いただきありがとうございます! この投稿は役に立ちましたか? 役に立った 役に立たなかった

Be the first to comment

コメント投稿

Your email address will not be published.


*