Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java CountDownLatch waits for the timeout value when the thread.run() counting down the latch gets an exception

I am using a CountDownLatch to handle two Java threads. My class structure is as follows:

MainClass.java
ThreadOne.java
ThreadTwo.java

MainClass:

CountDownLatch latch = new CountDownLatch(2);           
Thread thread = new Thread(new ThreadOne(latch));
thread.start();

Thread thread1 = new Thread(new ThreadTwo(latch));
thread1.start();        

latch.await(20, TimeUnit.SECONDS);

Main class waits until other two threads complete their work. As soon as they complete their work it does not wait until its timeout value (20 secs). My problem is if any of the threads get destroyed or corrupted then the CountDownLatch waits for its timeout value. Is there any way to ignore that interrupted thread and move forward without waiting 20 seconds?

like image 823
NPrasad Avatar asked May 18 '16 11:05

NPrasad


People also ask

What is true about Java CountDownLatch?

A CountDownLatch is a versatile synchronization tool and can be used for a number of purposes. A CountDownLatch initialized with a count of one serves as a simple on/off latch, or gate: all threads invoking await wait at the gate until it is opened by a thread invoking countDown() .

Does CountDownLatch block thread?

Simply put, a CountDownLatch has a counter field, which you can decrement as we require. We can then use it to block a calling thread until it's been counted down to zero.

Why CountDownLatch is used in Java?

CountDownLatch is used to make sure that a task waits for other threads before it starts. To understand its application, let us consider a server where the main task can only start when all the required services have started.


1 Answers

zapl is absolutely right! The main thread is waiting for the timeout to get over. If you took a thread dump during the time that the main thread is waiting on the latch, you will see something like:

"main" #1 prio=5 os_prio=31 tid=0x00007fa4be002000 nid=0x1303 waiting on condition [0x000000010b74c000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000076abcb598> (a java.util.concurrent.CountDownLatch$Sync)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:1037)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1328)
    at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:277)

From the Javadoc of await:

If the current count is greater than zero then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of three things happen:

  1. The count reaches zero due to invocations of the countDown method; or
  2. Some other thread interrupts the current thread; or
  3. The specified waiting time elapses.

In your case, the await call returns only because of 3).

In the CountDownLatch Javadoc, the call to the countDown() method should have been done in the finally block:

public void run() {
    try {
        startSignal.await();
        doWork(); // may throw exception
    } catch (InterruptedException ex) {
        // handle interruption ...
    } finally {
        doneSignal.countDown(); // cause await to return asap
    }
}
like image 82
Kedar Mhaswade Avatar answered Sep 29 '22 01:09

Kedar Mhaswade