Reputation: 6763
I want a method that runs 2 or more methods in separate threads. I want be sure that method won't finish before all threads are done.
Upvotes: 2
Views: 208
Reputation: 6763
My solution is
Function:
public void runParallel(Runnable... runnables) throws InterruptedException {
List<Thread> threads = new ArrayList<Thread>(runnables.length);
for (Runnable runnable :runnables) {
Thread th = new Thread(runnable);
threads.add(th);
th.start();
}
for (Thread th : threads) {
th.join();
}
Use:
runParallel(new Runnable() {
@Override
public void run() {
method1()
}
}, new Runnable() {
@Override
public void run() {
method2()
}
}
);
any better ideas? Maybe there is a shorter way that I'm not aware of ;)
Upvotes: 2
Reputation: 200206
The best approach is to utilize the Executor Service API to manage a thread pool instead of starting an open-ended number of threads on your own.
ExecutorService pool = Executors.newCachedThreadPool();
for (Runnable r : new Runnable[] {
new R() { void r() { myMethod1(); }},
new R() { void r() { myMethod2(); }},
})
pool.execute(r);
pool.shutdown();
pool.awaitTermination(60, TimeUnit.SECONDS);
abstract class R implements Runnable
public final void run() { r(); }
abstract void r();
}
Note that it is not advisable to insist on every method running in its own, separate thread. Threads are quite heavyweight (each allocating a complete call stack) and performance actually decreases as the thread count increases far beyond the number of available processor cores.
Upvotes: 6
Reputation: 340873
Following the API given by damienix:
public void runParallel(Runnable... runnables) throws InterruptedException {
final ExecutorService pool = Executors.newFixedThreadPool(runnables.length);
for (Runnable runnable: runnables) {
pool.submit(runnable);
}
pool.shutdown();
pool.awaitTermination(1, TimeUnit.MINUTES);
}
Upvotes: 0
Reputation: 242716
I prefer something like this:
public static void runParallel(Runnable... runnables) throws InterruptedException {
final CountDownLatch done = new CountDownLatch(runnables.length);
for (final Runnable r: runnables) {
new Thread(new Runnable() {
public void run() {
try {
r.run();
} finally {
done.countDown();
}
}
}).start();
}
done.await();
}
An advantage of this approach is that it also works with thread pool (i.e. you can replace new Thread(...).start()
with executor.submit(...)
).
Also it allows you to use pre-existing thread pool, unlike solutions based on awaitTermination()
that force you to create new pools for each invocation.
Upvotes: 2