Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8: Parallel FOR loop

I have heard Java 8 provides a lot of utilities regarding concurrent computing. Therefore I am wondering what is the simplest way to parallelise the given for loop?

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);
    }
}
like image 353
Joe Inner Avatar asked Dec 19 '14 01:12

Joe Inner


People also ask

Is forEach parallel Java?

parallel foreach() Works on multithreading concept: The only difference between stream(). forEach() and parallel foreach() is the multithreading feature given in the parallel forEach(). This is way faster that foreach() and stream.

How do you run two methods parallel in Java?

Do something like this: For each method, create a Callable object that wraps that method. Create an Executor (a fixed thread pool executor should be fine). Put all your Callables in a list and invoke them with the Executor.

Is parallel stream faster than for loop?

Conclusion: If you have a small list; for loops perform better, if you have a huge list; a parallel stream will perform better. And since parallel streams have quite a bit of overhead, it is not advised to use these unless you are sure it is worth the overhead.


4 Answers

Read up on streams, they're all the new rage.

Pay especially close attention to the bit about parallelism:

"Processing elements with an explicit for-loop is inherently serial. Streams facilitate parallel execution by reframing the computation as a pipeline of aggregate operations, rather than as imperative operations on each individual element. All streams operations can execute either in serial or in parallel."

So to recap, there are no parallel for-loops, they're inherently serial. Streams however can do the job. Take a look at the following code:

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

    servers.parallelStream().forEach((server) -> {
        serverData.put(server.getIdentifier(), server.fetchData());
    });
like image 145
Reinstate Monica Avatar answered Oct 03 '22 19:10

Reinstate Monica


That would be using a Stream:

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

I suspect a Collector can be used to greater effect here, since you use a concurrent collection.

like image 34
fge Avatar answered Oct 03 '22 18:10

fge


More elegant or functional solution will be just using Collectors toMap or toConcurrentMap function, which avoid maintaining another stateful variable for ConcurrentHashMap, as following example:

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

Note: 1. Those functional interfaces (Server::getIdentifier or Server::fetchData) doesn't allow throw checked exception here, 2. To get the full benefits of parallel stream, the number of servers would be large and there is no I/O involved, purely data processing in those functions(getIdentifier, fetchData)

Please refer to Collectors javadoc at http://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#toConcurrentMap

like image 32
zd333 Avatar answered Oct 03 '22 17:10

zd333


Simple example to copy'n'paste (the examples above use the class Server which is a custom class written by the OP):

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);
});

Console output. The order could possibly vary as everything executes in parallel:

Item1
Item2

The .parallelStream() method was introduced in Java v8. This example was tested with JDK v1.8.0_181.

like image 36
Contango Avatar answered Oct 03 '22 17:10

Contango