1

For some processing, n threads needs to spawned and runs in parallel. The main thread, which starts the processing should exit, after all the processing is done.

Here is the code snippet:

private void spawnThreads2(int n) throws InterruptedException {
  final CountDownLatch latch = new CountDownLatch(n);
  final Random random = new Random(System.currentTimeMillis());
  for (int i = 1; i <= n; i++) {
    final int id = i;
    new Thread(){
      public void run() {
        try {
          Thread.sleep(random.nextInt(1000)); // represents processing, can throw any Exception
        } catch (Exception e) {} 
        finally {
          latch.countDown();
        }
      }
    }.start();
  }
  latch.await();
  System.out.println("all completed.");
}

The countdown() is done in the finally block, so in case any exception happens application does not hang.

  1. Is this design good for creating threads and waiting for them? Is there possibility application can hang and never come out, because of the await()?
  2. Is there a way we can achieve same functionality using join()? We can store all the instance of the threads and check for status and wait. Is that a good way to do this.
YoungHobbit
  • 13,254
  • 9
  • 50
  • 73
  • @Gavriel still `Is there possibility application can hang and never come out, because of the await()` is not clear from the above queation. – YoungHobbit Jan 15 '16 at 08:03
  • well if any of the threads would have an endless loop, for example, then that thread would not end, and then your app would not end of course – Gavriel Jan 15 '16 at 08:07
  • I prefer invokeAll of ExecutorService. http://stackoverflow.com/questions/31612697/what-is-the-right-way-to-use-java-executor/34784526#34784526. If you didn't handle exception properly, Countdownlatch may wait. – Ravindra babu Jan 15 '16 at 08:17
  • Why are you holding onto the `main` thread? Why not let it return? – Peter Lawrey Jan 15 '16 at 13:05
  • BTW: You can have multiple Random in the same milli-second. You would get better off not using currentTimeMillis as a seed. The default uses System.nanoTime() and a counter. – Peter Lawrey Jan 15 '16 at 13:06

1 Answers1

1

You should use an ExecutorService. You can obtain one using n threads by calling:

ExecutorService executor = Executors.newFixedThreadPool( n );

Then, you can start a task as follow:

executor.submit( runnable );

At the end, you can stop executor by calling shutdown() method. Doing that, no task can be added anymore but all submitted tasks will be executed. You can also wait for shutdown:

executor.shutdown();

while ( !executor.isTerminated() ) {
    try {
        executor.awaitTermination( 5, TimeUnit.SECONDS);
    } catch ( InterruptedException e ) {
    }
}
Prim
  • 2,880
  • 2
  • 15
  • 29
  • The `while` loop is unnecessary. Rather set a long enough timeout and if it's still not finished, then force quit. – Kayaman Jan 15 '16 at 13:04