0

I am curious whether it is possible to pause a thread t in Java and allow another thread to resume it later, by having t run the following pause code:

while(true) {
  try {
    synchronized(t) { 
      t.wait();
    }
  } catch(InterruptedException e) {
    break;
  }
}

And then resuming the thread t by calling .interrupt() on it. However, I have read about spurious wake-ups, and so I wondered whether my code can fail, in the sense of exiting the while-loop despite no other thread calling .interrupt() on it. While this answer and this answer state that there are no spurious interrupts, and hence my code will never fail, the Java docs does not seem to address this. My question probably boils down to whether InterruptedException is ever thrown without the thread being interrupted by .interrupt(). Is there any official source or documentation that confirms this?

user21820
  • 569
  • 8
  • 17
  • Regardless of whether there are spurious interrupts, I don't think `interrupt()` is a good idea in this case, a volatile boolean field should do the trick instead. – biziclop Aug 20 '18 at 15:39
  • 1
    Interrupting a thread is not the best way to resume it, saying the least. – khachik Aug 20 '18 at 15:39
  • 4
    Why would you use `synchronized` on a thread object? You synchronize an object used by multiple threads, not the threads themselves. Use `wait` and `notify` to pause and resume. – Susmit Agrawal Aug 20 '18 at 15:40
  • Also, unless this is for learning purposes, you could probably just pick from `java.util.concurrent` a class that does exactly what you need, in your case probably a `CountdownLatch` or a `CyclicBarrier`. – biziclop Aug 20 '18 at 15:43
  • @SusmitAgrawal: Well only the thread itself is supposed to pause itself, and the `synchronized` is there because Java requires it... – user21820 Aug 20 '18 at 15:43
  • 1
    @biziclop: I would like to know exactly how it works or doesn't work, so you could say it's for my learning purposes. – user21820 Aug 20 '18 at 15:44
  • @user21820 Have you read [this](https://docs.oracle.com/javase/tutorial/essential/concurrency/)? It's a very good starter guide for what's what in the rather complicated Java concurrency model. (In any case, you're not supposed to synchronise on threads, you can create a dedicated private lock object for that.) – biziclop Aug 20 '18 at 15:45
  • @user21820 You should read up on what exactly `synchronized` does. To get a gist of it, `synchronized` is used when two or more different threads use the same object, to prevent the object from being accessed from the threads simultaneously. – Susmit Agrawal Aug 20 '18 at 15:45
  • @SusmitAgrawal: I know that, though from a language perspective it makes little sense why `.wait()` must be enclosed in a synchronized block. In any case, my question is whether my code works as stated, not whether there are other ways to achieve the same goal. – user21820 Aug 20 '18 at 15:47
  • i don't think you are interpreting the linked answers correctly. – Nathan Hughes Aug 20 '18 at 18:22
  • @NathanHughes: Okay, then please post your own answer, with official documentation, thanks! – user21820 Aug 21 '18 at 03:41

1 Answers1

1

Summary

So, although technically this works, there are numerous reasons why this should not be done. Oracle's documentation states that interruption should only be utilized for cancellations. But if you were to do this, it will clear the interrupt status and the previously waiting thread will receive an InterruptedException.


Alternative

Lets step through a brief, simplified example.

Object obj = new Object;
synchronized (obj) {
    while(condition) {
        obj.wait();
    }
} 
  1. A thread here will obtain the monitor.

  2. The thread will begin to wait via wait(), and release the monitor. Always utilize wait() inside a conditional because threads are subject to get spurious wake-ups from wait(). At this point, you have achieved forcing a thread to wait.

Lets investigate how we go about returning the thread to work.

synchronized(obj) {
    obj.notify();
}

The notify() will wake up the first waiting thread on the monitor. Now, if you want all waiting threads to wake up, utilize notifyAll() instead. This is the intended purpose and functionality of wait()/notify() and thus should be utilized over wait()/interrupt(). For an additional example, see this article.

Impurity
  • 1,037
  • 2
  • 16
  • 31
  • Thanks for your answer, but my real question remains: "Is there any official source or documentation that confirms this?". As for the 'intended purpose and functionality' of `wait()` and `notify()`, I am aware of them. However, as you said, `notify()` wakes up the first thread waiting on `obj`, and that is why I used `t.wait()` instead, so that each thread `t` that pauses itself waits on a unique monitor and any other thread that has a reference to `t` can resume `t`. Also, I was intrigued by the 2 answers stating that there are no spurious interrupts. – user21820 Aug 21 '18 at 03:47
  • Yes and that is why I said that my real question remains unanswered. Remember, I am asking for **official documentation** that confirms that when a thread is interrupted it **must always be** due to a `.interrupt()`. Your answer is now the third one I know about on SO that says so, but *Nathan Hughes* in a comment on my question seems to cast doubt on that. That's why I would like official documentation, or at least information from someone who has actually seen the Java implementation. Thanks! – user21820 Aug 21 '18 at 09:38
  • "A thread sends an interrupt by invoking *interrupt* on the `Thread` object for the thread to be interrupted. " https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html – Impurity Aug 21 '18 at 11:23
  • So you are saying that the lack of mention of spurious interrupts implies that it is not possible? I've seen that reasoning a lot around here, and it's not very convincing to me. – user21820 Aug 21 '18 at 11:35
  • No, your just asking for something to explicitly support your claim, while I provide you with evidence in the docs that you asked for. – Impurity Aug 21 '18 at 11:37
  • Thanks for that piece of implicit evidence, but that's not what I asked for. I was very careful to use the phrases "never fail" and "must always" in my post and comments, because I don't want just implicit evidence. If your evidence is the best that anyone can provide, then I would take it, but it would frankly be disappointing. – user21820 Aug 21 '18 at 11:42
  • It's actually explicit, it states how a thread is interrupted, thus disproving spurious interrupts. Either way, good luck! – Impurity Aug 21 '18 at 11:44
  • Actually it's not. The quote, for example, tells us how a thread can send an interrupt, because after all the docs are aimed at programmers who want to know the answer to "how can I interrupt that thread?". The quote does not tell us whether there is absolutely no other way that a thread can get interrupted (some other programming languages appear to have the issue of spurious interrupts), and that's what I'm looking for. Thanks anyway! =) – user21820 Aug 21 '18 at 11:47
  • I would recommend reading exactly the purpose of a thread interrupt to further understand the implications of what myself and others are trying to tell you as the answer is here, I just think there's a misunderstanding. – Impurity Aug 21 '18 at 11:51