Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Impossible to interrupt thread if its actually computing?

Given this code...

public class SimpleTest {

  @Test
  public void testCompletableFuture() throws Exception {
    Thread thread = new Thread(SimpleTest::longOperation);
    thread.start();

    bearSleep(1);

    thread.interrupt();

    bearSleep(5);
  }

  public static void longOperation(){
    System.out.println("started");
    try {

      boolean b = true;
      while (true) {
        b = !b;
      }

    }catch (Exception e){
      System.out.println("exception happened hurray!");
    }
    System.out.println("completed");
  }

  private static void bearSleep(long seconds){
    try {
      TimeUnit.SECONDS.sleep(seconds);
    } catch (InterruptedException e) {}
  }
}

Imagine that instead of this while(true) you have something that does not throw interrupted execution (for example, a recursive function that actually calculates something).

How do you kill this thing? And why is it not dying?

Note if I don't put Exception type there and use InterruptedException it won't even compile, saying that "interrupted exception will never be thrown" which I don't understand why. Maybe I want to interrupt it manually...

like image 266
vach Avatar asked Mar 12 '15 16:03

vach


People also ask

Can a thread be interrupted?

interrupt() method: If any thread is in sleeping or waiting for a state then using the interrupt() method, we can interrupt the execution of that thread by showing InterruptedException. A thread that is in the sleeping or waiting state can be interrupted with the help of the interrupt() method of Thread class.

What happens if thread is interrupted?

Threads can be interrupted, and when a thread is interrupted, it will throw InterruptedException. In the next sections, we'll see InterruptedException in detail and learn how to respond to it.

What are interrupting threads?

An interrupt is an indication to a thread that it should stop what it is doing and do something else. It's up to the programmer to decide exactly how a thread responds to an interrupt, but it is very common for the thread to terminate.

How do you make a thread interrupted?

The interrupt() method of thread class is used to interrupt the thread. If any thread is in sleeping or waiting state (i.e. sleep() or wait() is invoked) then using the interrupt() method, we can interrupt the thread execution by throwing InterruptedException.


2 Answers

I assume you are referring to this segment of code:

try {
    boolean b = true;
    while (true) {
        b = !b;
    }
} catch(Exception e) {
    System.out.println("exception happened hurray!");
}

The reason you cannot catch an InterruptedException here is because there is nothing inside of that block that can throw an InterruptedException. interrupt() itself will not break the thread out of the loop, instead, it essentially sends a signal to the thread to tell it to stop what it's doing and do something else. If you want interrupt() to break the loop, try this:

boolean b = true;
while (true) {
    b = !b;
    // Check if we got interrupted.
    if(Thread.interrupted()) {
        break; // Break out of the loop.
    }
}

Now the thread will check if it got interrupted, and break out of the loop once it has. No try-catch necessary.

like image 188
Minty Fresh Avatar answered Oct 10 '22 22:10

Minty Fresh


Thread#interrupt is more or less implemented with a flag. If the thread is blocked on some actions, ex: IO or synchronization primitives (see Javadoc), the thread is unblocked and an InterruptedException, is thrown in that thread. Otherwise, a simple status flag is set indicating that the thread was interrupted.

Your code needs to check for that status with Thread#interrupted() or Thread#isInterrupted() (or handle the InterruptedException).

Note that checking for the status with the static method clears the status.

like image 22
Sotirios Delimanolis Avatar answered Oct 11 '22 00:10

Sotirios Delimanolis