damienix
damienix

Reputation: 6763

What is the simplest way in java to run many methods in separate threads and wait until all will be finished?

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

Answers (4)

damienix
damienix

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

Marko Topolnik
Marko Topolnik

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

Tomasz Nurkiewicz
Tomasz Nurkiewicz

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

axtavt
axtavt

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

Related Questions