2

(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();
      }
 }));
Laird Nelson
  • 15,321
  • 19
  • 73
  • 127
  • Well the interrupted status being cleared does make sense from reading the javadoc on CountDownLatch's `await()` method. – Roddy of the Frozen Peas Sep 30 '19 at 23:02
  • Thank you for your comment. `InterruptedException` is never thrown. – Laird Nelson Sep 30 '19 at 23:08
  • 1
    Can you post the demo code? I used your snippets on JDK 11 and I'm getting `*** done via interrupt` when I Ctrl+C. Also, what JDK are you using? – Malt Sep 30 '19 at 23:19
  • Thank you for your comment. JDK 8 build, uh, _checks notes_ 181. On a Mac. I can't post my demo code at the moment other than the excerpt above. I take it from your comment that I'm not missing anything obvious. – Laird Nelson Sep 30 '19 at 23:24
  • @LairdNelson Honestly, I haven't tried anything else yet. Just tried running it. Tried in on JDK8 (u201) now with the same result. My test code is trivial - just a main method that defines a `new CountDownLatch(1)`, then runs your shutdownHook snippet, then your wait snippet. – Malt Sep 30 '19 at 23:57
  • Thanks. I'm going to proceed under the assumption that I am _not_ seeing a spurious wakeup, but I'll be darned if I can figure out how `countDown()` is being called. It doesn't help that `java.util.logging.LogManager` begins shutting down logs at shutdown hook time so my logging statements are useless. Back to `System.out.println()`! – Laird Nelson Oct 01 '19 at 00:00
  • The code you've pasted doesn't compile due to a missing semicolon, so it's obviously been redacted. Are you sure you haven't redacted anything important? Try creating an MCVE with just a main that creates a latch, registers a shutdownhook, then waits. – Malt Oct 01 '19 at 00:02

1 Answers1

1

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().

Laird Nelson
  • 15,321
  • 19
  • 73
  • 127