2

I am reading Google Guava RateLimiter. The acquire method will put thread to uninterruptible uninterruptible sleep while waiting for new permit. InterruptedException

The uninterruptible sleep doesn't totally ignore InterruptedException. But just catch it, remember that it has been interrupted and then continue sleep until reach timeout. It will finally set the interrupted flag back to the thread nicely.

List item

  • This prevent caller to cancel the wait by interrupting. What might be the benefit of it? Is it just because the method doesn't what to force caller to handle InterruptedException?
  • What are other use cases that we might want to use the same pattern of uninterruptible code?

Edit: I just realised I linked it to incorrect method.

public static boolean awaitUninterruptibly(Condition condition, long timeout, TimeUnit unit)

The correct method is sleepUninterruptibly.

public static void sleepUninterruptibly(long sleepFor, TimeUnit unit) {
    boolean interrupted = false;
    try {
      long remainingNanos = unit.toNanos(sleepFor);
      long end = System.nanoTime() + remainingNanos;
      while (true) {
        try {
          // TimeUnit.sleep() treats negative timeouts just like zero.
          NANOSECONDS.sleep(remainingNanos);
          return;
        } catch (InterruptedException e) {
          interrupted = true;
          remainingNanos = end - System.nanoTime();
        }
      }
    } finally {
      if (interrupted) {
        Thread.currentThread().interrupt();
      }
    }
  }
Devguli
  • 51
  • 5
  • "Is it just because the method doesn't what to force caller to handle InterruptedException" - callers would not receive an `InterruptedException`. They could check what happened via `isInterrupted`, but they would not get that exception. It is weird that this method returns a boolean, when the same status could be checked simply with `isInterrupted` method. Probably it is just an enforcement so that the caller has to think about the result, just like `Optional` is a return type from a method instead of `null` – Eugene May 02 '21 at 13:57
  • Yes, that is what I thought. The only benefit I can see by not propagate `InterruptedException` up is the caller doesn't need to think about how to handle the exception. But I don't know it is worth denying option for caller to cancel the wait by interrupting it. – Devguli May 02 '21 at 18:09

1 Answers1

0

Is it just because the method doesn't what to force caller to handle InterruptedException

callers would not receive the InterruptedException. Thread.currentThread().interrupt(); only sets an inner flag, it does not throw that InterruptedException.

There are probably (I don't know a real one) cases where waiting without being interrupted would make sense. I do know a theoretical one that can happen because of "spurious interrupts", i.e.: interrupts for no real reason directly dependent on your code, as documented here:

When waiting upon a Condition, a "spurious wakeup" is permitted to occur, in general, as a concession to the underlying platform semantics.

Eugene
  • 117,005
  • 15
  • 201
  • 306
  • Hi Eugene, your reply made I realised that I linked to wrong code. It is actually `sleepUninterruptibly`. I believe thread sleep doesn't get affected by spurious wake up. – Devguli May 06 '21 at 10:43
  • @Devguli [this](https://stackoverflow.com/questions/1050592/do-spurious-wakeups-in-java-actually-happen) tends to disagree with you. – Eugene May 06 '21 at 14:50
  • I can see that your link mentions only the case of `wait` (as in wait/notify). I believe it is not apply for `Thread.sleep()` - [ref](https://stackoverflow.com/questions/2388850/do-spurious-wakeups-affect-thread-sleep) – Devguli May 06 '21 at 20:51
  • A spurious wakeup is a wakeup, not an interruption, isn't it? – gdabski Dec 23 '22 at 10:25