Search code examples
javajava.util.concurrent

How can a CountDownLatch that is not counted down to zero return without being interrupted?


(For posterity, I'm familiar with this other question, and its answer which would seem to suggest the case I'm observing is impossible: Is CountDownLatch affected by spurious wakeups?)

I have a CountDownLatch that is created with an int argument of 1. Deliberately, countDown() is never called on this latch.

I have a ShutdownHook that interrupts the thread that calls myLatch.await(), and I have a catch block that deals with the subsequent InterruptedException.

I'm observing that when my shutdown hook is invoked, the latch "wakes up" normally. That is, the await() method returns, the thread is not interrupted, and its interrupted status (as reported by isInterrupted()) is false.

My understanding from the CountDownLatch documentation is that this scenario is impossible. What am I missing?

The code where the latch is awaited looks like this:

try {
    myLatch.await();
    System.out.println("*** done via unblock");
} catch (final InterruptedException interruptedException) {
    Thread.currentThread().interrupt();
    System.out.println("*** done via interrupt");
}

I see *** done via unblock when I CTRL-C my application. My read of the documentation is that this is impossible because CountDownLatch instances are not subject to spurious wakeups.

The shutdown hook code looks like this:

// t is the thread that is doing the await() call above
final Thread t = Thread.currentThread();
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
      t.interrupt();
      try {
          t.join();
      } catch (final InterruptedException interruptedException) {
        Thread.currentThread().interrupt();
      }
 }));

Solution

  • Thankfully I have found a codepath where several classes away something is indeed counting down the latch in question. Thank goodness, since (a) my code now works and (b) the documentation is correct and spurious wakeups are in fact Not A Thing™ when we're talking about CountDownLatch#await().