web-dev-qa-db-ja.com

Java 8:並列FORループ

Java 8はコンカレントコンピューティングに関する多くのユーティリティを提供していると聞きました。したがって、指定されたforループを並列化する最も簡単な方法は何ですか?

public static void main(String[] args)
{
    Set<Server> servers = getServers();
    Map<String, String> serverData = new ConcurrentHashMap<>();

    for (Server server : servers)
    {
        String serverId = server.getIdentifier(); 
        String data = server.fetchData();

        serverData.put(serverId, data);
    }
}
60
Joe Inner

streams を読んで、彼らはすべて新しい怒りです。

並列処理に関するビットには特に細心の注意を払ってください。

「明示的なforループを使用した要素の処理は本質的にシリアルです。ストリームは、個々の要素に対する命令型演算としてではなく、集計演算のパイプラインとして計算を再フレーミングすることにより、並列実行を容易にします。すべてのストリーム演算は、シリアルまたはパラレルで実行できます。 」

要約すると、並列forループはなく、本質的に直列です。ただし、Streamsがジョブを実行できます。次のコードを見てください。

    Set<Server> servers = getServers();
    Map<String, String> serverData = new ConcurrentHashMap<>();

    servers.parallelStream().forEach((server) -> {
        serverData.put(server.getIdentifier(), server.fetchData());
    });
82
A Boschman

それはStreamを使用します:

servers.parallelStream().forEach(server -> {
    serverData.put(server.getIdentifier(), server.fetchData());
});

Collectorを使用すると、並行コレクションを使用するため、ここでより大きな効果が得られると思われます。

18
fge

よりエレガントで機能的なソリューションは、次の例のように、ConcurrentHashMapの別のステートフル変数を維持することを避けるために、コレクターのtoMapまたはtoConcurrentMap関数を使用することです。

final Set<Server> servers = getServers();
Map<String, String> serverData = servers.parallelStream().collect(
    toConcurrentMap(Server::getIdentifier, Server::fetchData));

注:1.これらの機能インターフェース(Server::getIdentifier or Server::fetchData)は、ここでチェック例外のスローを許可しません。2.並列ストリームの利点を最大限に活用するには、サーバーの数が多く、I/Oが関与しません。それらの関数での純粋なデータ処理(getIdentifier, fetchData

http://docs.Oracle.com/javase/8/docs/api/Java/util/stream/Collectors.html#toConcurrentMap のコレクターjavadocを参照してください。

5
zd333

コピーアンドペーストの簡単な例(上記の例では、OPによって記述されたカスタムクラスであるServerクラスを使用しています):

import Java.io.Console;
import Java.util.ArrayList;

ArrayList<String> list = new ArrayList<>();
list.add("Item1");
list.add("Item2");
list.parallelStream().forEach((o) -> {
    System.out.print(o);
});

コンソール出力。すべてが並行して実行されると、順序が変わる可能性があります。

Item1
Item2

.parallelStream()メソッドはJava v8で導入されました。この例は、JDK v1.8.0_181でテストされました。

1
Contango