Reputation: 1427
I have the following loop:
// myList is an ArrayList (10000 elements)
for(MyObject test : myList) {
test.calculate();
}
And I thought that it is a good candidate to parallelization since every calculate()
operation does not depend on anything else, it only makes some math operations using some variables within the same object.
I know doing the following will have a negative impact on performance since I will be creating 10000 threads which will create a huge queue on my 4 cores processor:
// myList is an ArrayList (10000 elements)
for(MyObject test : myList) {
Thread thread = new Thread() {
public void run() {
test.calculate();
}
};
thread.start();
}
The question is, what's the recomended way to work with multiple threads on this type of scenarios to avoid queuing?
Upvotes: 0
Views: 79
Reputation: 4578
A simpler approach is to take advantage of Java 8 parallel streams.
myList.parallelStream().forEach( MyObject::calculate);
The JVM maintains a pool of threads for such tasks, with as many threads as there are cores (or hyperthreads) on the computer. It does not spin up a new pool every time it encounters parallel code; nor does it spin up a new thread for every iteration.
Of course, with any performance issue, do benchmarking. There is some overhead to forking work among multiple threads and then joining the results (presumably you want to capture the results). So make sure the savings outweigh the overhead.
Upvotes: 3
Reputation: 328598
A simple approach would be to use an ExecutorService
- based on your description, you want to use one thread per processor:
int nThreads = Runtime.getRuntime().availableProcessors();
ExecutorService executor = Executors.newFixedThreadPool(nThreads);
for (MyObject test: myList) {
executor.submit(test::calculate);
}
executor.shutdown();
The executor maintains an internal queue which will hold the tasks until the previous ones are completed.
Upvotes: 5