简体   繁体   中英

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

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM