Java Iterator Concurrency

I am trying to iterate over a Java iterator at the same time, but I have problems with a better way to do this.

This is what I have, where I am not trying to do anything at the same time.

Long l; Iterator<Long> i = getUserIDs(); while (i.hasNext()) { l = i.next(); someObject.doSomething(l); anotheObject.doSomething(l); } 

There should be no race conditions between the things that I do on objects without an iterator, so I'm not too worried about that. I just wanted to speed up how long it would take to go through the iterator without having to execute it sequentially.

Thanks in advance.

+6
source share
3 answers

One solution is to use an artist to parallelize your work.

A simple example:

 ExecutorService executor = Executors.newCachedThreadPool(); Iterator<Long> i = getUserIDs(); while (i.hasNext()) { final Long l = i.next(); Runnable task = new Runnable() { public void run() { someObject.doSomething(l); anotheObject.doSomething(l); } } executor.submit(task); } executor.shutdown(); 

This will create a new thread for each element in the iterator, which will then do the job. You can configure how many threads are used with another method in the Executors class, or split the work as you like (for example, another Runnable for each method call).

+4
source

A can offer two possible approaches:

  • Use the thread pool and send the elements received from the iterator to the set of processing threads. This will not speed up the iterator operations themselves, since they will still happen in the same thread, but will parallelize the actual processing.

  • Depending on how the iteration is created, you can divide the iteration process into several segments, each of which will be processed by a separate thread through another Iterator object. For example, see List.sublist(int fromIndex, int toIndex) and List.listIterator(int index) .

    This will allow you to perform iterator operations in parallel, but it is not always possible to segment the iteration, as this is usually due to the simple fact that the elements that need to be iterated are not immediately available.

  • As a bonus trick, if iteration operations are expensive or slow, for example, required to access the database, you can see an increase in throughput if you select them in a separate stream, which the iterator will use to fill out the BlockingQueue . Then the dispatcher thread will have access only to the queue, not waiting until the iterator object receives the next element.

The most important piece of advice in this case is: "Use your profiler," usually for this, "Don't optimize prematurely." Using a profiler like VisualVM , you should be able to figure out the exact cause of any performance problems without taking pictures in the dark.

+5
source

If you are using Java 7, you can use the new fork / join; see tutorial .

It not only automatically splits tasks among threads, but if a thread finishes its tasks before other threads, it β€œsteals” some tasks from other threads.

+1
source

Source: https://habr.com/ru/post/909398/


All Articles