Amit
Amit

Reputation: 34745

How to join one thread with other in java?

I have one main thread that starts 10 other threads. I want that the main thread will be finished only after all other threads stopped. So should I call join() on other 10 threads before starting or after starting them. For instance:

// in the main() method of Main thread
Thread [] threads = new Thread[10];
for(int i = 0; i < 10; i++) {
    // ParserThread() is a runnable thread
    threads[i] = new Thread(new ParserThread());
    threads[i].join();
    threads[i].start();
}
System.out.println("All threads have been finished"); // line no. 9
  1. So as in the above example, should i call join() before start() or after start().
  2. Will the control returns to line no. 9 only after all the threads have finished.
  3. When the run method of any thread has been executed, then will that thread die or remain alive. If it will, the how to die all the threads when their run method has finished means when the control returns to line no. 9

Upvotes: 4

Views: 3109

Answers (5)

honzajde
honzajde

Reputation: 2398

Case can be that you want to join group of threads. See javadoc for

http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorCompletionService.html

 void solve(Executor e,
              Collection<Callable<Result>> solvers)
     throws InterruptedException, ExecutionException {
       CompletionService<Result> ecs
           = new ExecutorCompletionService<Result>(e);
       for (Callable<Result> s : solvers)
           ecs.submit(s);
       int n = solvers.size();
       for (int i = 0; i < n; ++i) {
           Result r = ecs.take().get();
           if (r != null)
               use(r);
       }
   }

For trivial scenarios (one thread), Thread.join() is enough.

Upvotes: 0

sfussenegger
sfussenegger

Reputation: 36095

Instead of writing your own code, you code use a ThreadPoolExecutor to do what you need:

ThreadPoolExecutor executor = new ThreadPoolExecutor(0, 10, 2, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());

for (int i = 0; i < 10; i++)
    executor.execute(new ParserThread());

try {
    executor.shutdown();
    executor.awaitTermination(10, TimeUnit.MINUTES);
} catch (final InterruptedException e) {
     // handle
}

This way, you could easily use less threads to do more tasks if you wish - without changing the code.

Upvotes: 5

skaffman
skaffman

Reputation: 403501

I recommend against using the low-level Thread constructs like join(), and instead using the higher-level stuff in java.util.concurrent, like CyclicBarrier:

A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point. CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting threads are released.

The usage is much more obvious that Thread.join(), and much less prone to weird bugs.

Upvotes: 7

Salandur
Salandur

Reputation: 6453

you should first start all the thread, then start joining them. Join will return direct if called before the thread is start.

Upvotes: 1

Greg Hewgill
Greg Hewgill

Reputation: 993323

Calling join() on a thread only makes sense after the thread is started. The caller of join() will stop and wait until the other thread finishes what it's doing. So you may want to do this:

// in the main() method of Main thread
Thread [] threads = new Thread[10];
for(int i = 0; i < 10; i++) {
    // ParserThread() is a runnable thread
    threads[i] = new Thread(new ParserThread());
    threads[i].start();
}
System.out.println("All threads have been started");
for(int i = 0; i < 10; i++) {
    threads[i].join();
}
System.out.println("All threads have been finished");

Upvotes: 8

Related Questions