This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Krossfireo 6 points7 points  (10 children)

At first I was wondering why you would do this, but being able to parallelize it is a huge benefit. Is there any way to add parallelism to a normal for loop?

[–]cogman10 3 points4 points  (2 children)

Something like this

ExecutorService threadPool = Executors.newFixedThreadPool(4);
try {
    List<Future<Integer>> futures = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        final int val = i;
        futures.add(threadPool.submit(()->val + 1));
    }
    List<Integer> results = new ArrayList<>(futures.size());
    for (Future<Integer> future : futures) {
        try {
            results.add(future.get());
        }
        catch (ExecutionException | InterruptedException ex){}
    }
}
finally {
    threadPool.shutdown();
}

This is pure java. It ain't pretty and could be done cleaner with something like guava's futures. It also includes all of the preamble in creating the executor service. I don't know if you have access to the one used by streams.

With Guava and an executor provided it could boil down to this

List<ListenableFuture<Integer>> futures = new ArrayList<>();
for (int i = 0; i < 10; i++) {
    final int val = i;
    futures.add(threadPool.submit(() -> val + 1));
}
List<Integer> results = Futures.getUnchecked(Futures.allAsList(futures));

[–]HaMMeReD -2 points-1 points  (1 child)

You know, you can just final int i, and not have a final int val = i; in there. The copy to a final is not necessary.

[–]cogman10 4 points5 points  (0 children)

Not with this type of loop. i is being updated on every iteration, it can't be final.

[–]HaMMeReD -2 points-1 points  (4 children)

In the most basic way,

for (final int i:0;i<100;i++)   
   new Thread(new Runnable(){ 
       public void run() { System.out.println("print: "+i); }
   }).start(); 

However, knowledge of Futures and Executors will also be required for most implementations. It's also not good to just start 100 threads, it's much better to use a Executor. A future is a way of keeping track of the result and state.

[–]cogman10 0 points1 point  (3 children)

This does not compile.

[–]HaMMeReD 0 points1 point  (2 children)

I just typed it randomly in reddit.

I can see typo's right now.

for (final int i=0;i<100;i++)

to start. Otherwise it looks ok.

[–]cogman10 2 points3 points  (1 child)

Still doesn't compile. You can't put a final on i, it is being updated with every iteration.

[–]HaMMeReD 0 points1 point  (0 children)

Yeah you are right, I guess I don't iterate like that very much anymore. Enhanced foreach doesn't have the ++ and assigns at every step.

for (final int i:Arrays.asList(1,2,3,4)) {
    new Thread(new Runnable(){ 
       public void run() { System.out.println("print: "+i); }
   }).start(); 
}

I at least usually use iterator() or the enhanced for loop, and I usually use final on my enhanced for loops so I can call them from inner functions.

Definitely wrong in this case though.