March 4, 2021

Thread Interruption in Java

Thread interrupt is an indication to a thread that it should stop doing what it is currently doing and either terminate or do something else. What a thread does after being interrupted is up to you but the convention is that a thread should be terminated once interrupted.

How thread interruption in Java works

In Java Thread class there is a method interrupt() which interrupts the calling thread. Once the thread is interrupted its interrupt status is set to true and then based on whether the thread is currently blocked or not following activity takes place-

  1. If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared (set to false again) and it will receive an InterruptedException.
  2. If this thread is blocked in an I/O operation upon an InterruptibleChannel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.
  3. If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.
  4. If a thread that is not blocked is interrupted, then the thread's interrupt status will be set.

Methods related to thread interruption in Java Thread class

Apart from the method interrupt() already discussed above there are two more methods in java.lang.Thread class related to thread interruption interrupted() and isInterrupted().

  • void interrupt()- Interrupts this thread.
  • static boolean interrupted()- Checks whether the current thread has been interrupted. Also clears the interrupted status of the thread.
  • boolean isInterrupted()- Tests whether this thread has been interrupted. This method doesn't change the interrupted status of the thread in any way.

Thread interruption examples

Thread interruption in Java is generally used to terminate a blocking thread. So you can choose to just return after interrupting a sleeping or waiting thread.

public class InterruptDemo implements Runnable {
	
  @Override
  public void run() {
    for(int i = 0; i < 5; i++){
      System.out.println("Value - " + i);
      try {
        Thread.sleep(500);
      } catch (InterruptedException e) {
        System.out.println("Thread " + Thread.currentThread().getName() + " interrupted, reason " + e.getMessage());
        System.out.println("Interrupted status- " + Thread.currentThread().isInterrupted());
        return;
      }
    }	
  }

  public static void main(String[] args) {
    Thread t = new Thread(new InterruptDemo());
    t.start();
    t.interrupt();
    System.out.println("In main method - Interrupted status " + t.isInterrupted());
  }
}
Output
In main method - Interrupted status true
Value - 0
Thread Thread-0 interrupted, reason sleep interrupted
Interrupted status- false

In the thread’s run method there is a loop to print number from 1 to 5, after each number display, sleep method is called on the thread. Thread’s interrupt method is also called in the mean time which interrupts the blocked thread. Also you can see that the interrupt status is true after the interrupt() method is called and later the interrupt status is cleared (set to false).

Wrapping and rethrowing the InterruptedException

Rather than just returning as done in the previous example you may choose to wrap the InterruptedException and rethrow it.

public class InterruptDemo implements Runnable {
  @Override
  public void run() {
    for(int i = 0; i < 5; i++){
      System.out.println("Value - " + i);
      try {
        Thread.sleep(500);
      } catch (InterruptedException e) {
        System.out.println("Thread " + Thread.currentThread().getName() + " interrupted, reason " + e.getMessage());
        System.out.println("Interrupted status- " + Thread.currentThread().isInterrupted());
        throw new RuntimeException("Thread interrupted", e);
      }
    }	
  }

  public static void main(String[] args) {
    Thread t = new Thread(new InterruptDemo());
    t.start();
    t.interrupt();
    System.out.println("In main method - Interrupted status " + t.isInterrupted());
  }
}
Output
In main method - Interrupted status true
Value - 0
Thread Thread-0 interrupted, reason sleep interrupted
Interrupted status- false
Exception in thread "Thread-0" java.lang.RuntimeException: Thread interrupted
	at com.knpcode.InterruptDemo.run(InterruptDemo.java:14)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.knpcode.InterruptDemo.run(InterruptDemo.java:10)
	... 1 more

Interrupting a non-blocking thread

If you interrupt a thread that is not blocking then just the interrupt status of the thread changes. Using the isInterrupted() method you can check the interrupt status of the thread and choose to execute some logic in that condition.

public class InterruptDemo implements Runnable {
  @Override
  public void run() {
    for(int i = 0; i < 5; i++){
      System.out.println("Value - " + i);
      if(Thread.currentThread().isInterrupted()){
        System.out.println("Interrupted status- " + Thread.currentThread().isInterrupted());
      }
    }	
  }

  public static void main(String[] args) {
    Thread t = new Thread(new InterruptDemo());
    t.start();
    t.interrupt();
    System.out.println("In main method - Interrupted status " + t.isInterrupted());
  }
}
Output
In main method - Interrupted status true
Value - 0
Interrupted status- true
Value - 1
Interrupted status- true
Value - 2
Interrupted status- true
Value - 3
Interrupted status- true
Value - 4
Interrupted status- true

As you can see in this case interrupt status remains true, not cleared to false as happens for the blocked threads which are interrupted.

That's all for the topic Thread Interruption in Java. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment