Java interrupt thread (interrupt) super detailed explanation

Java interrupt thread (interrupt)

@author: Jingdai
@date:2020.10.06

concept

When Aa thread wants Bthe thread terminates, how should we do it? In previous versions of Java, you can use stopthe method to make a thread to terminate, but this method has been abandoned, do not use it.

You can now Acalling thread in Bthe thread interrupt()method to the Bthread know you want to make your own thread to terminate, but depends on whether or not to terminate Ba thread yourself, Bcan ignore the termination request. (Of course it's better not to do this) Let's take a look at the details.

Related function introduction

  • void interrupt()

Interrupt this thread.

  • boolean isInterrupted()

Check if this thread is interrupted.

  • static boolean interrupted()

    Check whether the current thread is interrupted. This method will also clear the interruption status of the thread after it is called.

Example explanation

  • boolean isInterrupted()Method and static boolean interrupted()method difference

    First, the following code Test boolean isInterrupted()Method.

    public static void main(String[] args) {
           
           
        Thread.currentThread().interrupt();
        System.out.println(Thread.currentThread().isInterrupted()); // true
        System.out.println(Thread.currentThread().isInterrupted()); // true
    }
    

    You will find that the output is both times true.

    Then test static boolean interrupted()methods.

    public static void main(String[] args) {
           
           
        Thread.currentThread().interrupt();
        System.out.println(Thread.interrupted());  // true
        System.out.println(Thread.interrupted());  // false
    }
    

    The test found that the first output is true, and the second output is false, indicating that this method will clear the interruption status of the thread after it is called.

  • Interrupt and ignore

    Here we get the main thread interrupts thread aThread, but aThreadthe thread ignore, to see what happens. code show as below:

    public static void main(String[] args){
           
           
        // create and start aThread
        Runnable r = () -> {
           
           
            while (true) {
           
           
                System.out.println("I'm alive");
            }
        };
        Thread aThread = new Thread(r);
        aThread.start();
    
        // interrupt aThread
        aThread.interrupt();
    }
    

    Tests found aThreadno effect of running threads, or has been output I'm alive.

  • General usage

    Since there will be no effect if the interrupt is not processed, how should you respond to the interrupt? It should always be judged whether the thread is interrupted in the thread. If the thread is interrupted, the next work should be selected according to the requirements of the current task, and the necessary resources should be shut down before ending the thread. Look at the code below.

    public static void main(String[] args){
           
           
        // create and start aThread
        Runnable r = () -> {
           
           
            try {
           
           
                while (!Thread.currentThread().isInterrupted()) {
           
           
                    //do work
                    System.out.println("I'm alive");
                }
                System.out.println("I ll die");
            } finally {
           
           
                // close some resources
            }
    
        };
        Thread aThread = new Thread(r);
        aThread.start();
    
        try {
           
           
            Thread.currentThread().sleep(1);
        } catch (InterruptedException e) {
           
           
            e.printStackTrace();
        }
        // interrupt aThread
        aThread.interrupt();
    }
    

    When the thread has not been interrupted, has been implementing its mandate, when interrupted, it will be out of the loop and finallycloses the corresponding resources and do some clean-up and operation.

  • When the thread is blocked

    The above situation can be run in the thread is not blocked, but when the thread is blocked, the thread is unable to check the thread's interrupt status, so the introduction of InterruptedExceptionan exception to help break blocked. There are some differences between different blocking, as follows.

    • Thread sleep()method or join()when the method blocks

      The following code:

      public static void main(String[] args) {
               
               
          // create and start aThread
          Runnable r = () -> {
               
               
              try {
               
               
                  Thread.currentThread().sleep(5000);
              } catch (InterruptedException e) {
               
               
                  System.out.println("die");
                  e.printStackTrace();
              } finally {
               
               
                  // close some resources
              }
          };
          Thread aThread = new Thread(r);
          aThread.start();
      
          try {
               
               
              Thread.currentThread().sleep(500);
          } catch (InterruptedException e) {
               
               
              e.printStackTrace();
          }
          // interrupt aThread
          aThread.interrupt();
      }
      

      Calls on these threads interrupt()when the method, sleep()/join()the method will be interrupted no longer executed, it clears the interrupt status and directly jump into the catchblock in execution, so if you call in a loop sleep()method is not going to detect the interrupt status, as it will directly jump the catchblocks being performed, it should be directly captured InterruptedExceptionexception.

    • Thread is wait()when the method blocks

      Thread is wait()when blocking method, calling interrupt()effect and thread method is sleep()a method or join()blocking the effect of essentially the same way, it also clears the interrupt status and jumped into the catchblock to execute. But there is a little bit different, that is, the interrupt()calling thread will go to get called wait()lock object method, after obtaining the finished object will lock and thrown into the catchblock to execute, if not get a lock, then you can not throw an abnormality can not enter catchthe block. The following code, first aThreadobtain the lock and wait(note wait()method will release the lock), then bTheadget the lock, but bnever release the lock, at aThread waitthe time, the main thread calls interrupt()to interrupt aThread, but because aThreadnever get a lock, so it will not throw an exception, It does not enter into the catchblock operation. code show as below.

      public static void main(String[] args) {
               
               
              
          Runnable r = () -> {
               
               
              try {
               
               
                  synchronized (o) {
               
               
                      System.out.println("aThread get lock");
                      o.wait(10000);
                  }
              } catch (InterruptedException e) {
               
               
                  e.printStackTrace(); // can't come here
              } 
          };
          Thread aThread = new Thread(r);
          aThread.start();
      
          Runnable r2 = () -> {
               
               
              try {
               
               
                  Thread.currentThread().sleep(250);
                  synchronized (o) {
               
               
                      System.out.println("bThread get lock");
                      while (true) {
               
               
                      }
                  }
              } catch (InterruptedException e) {
               
               
                  e.printStackTrace();
              }
          };
          Thread bThread = new Thread(r2);
          bThread.start();
      
          try {
               
               
              Thread.currentThread().sleep(1000);
          } catch (InterruptedException e) {
               
               
              e.printStackTrace();
          }
          // interrupt aThread
          aThread.interrupt();
      }
      
    • Other blocking

      There are other blocking situations in the API. If the thread is InterruptibleChannelIO operation blocked, then the pipeline will be shut down, thread's interrupt status will be set, and it will throw an ClosedByInterruptExceptionexception.

      If the thread is Selectorblocked, then the thread's interrupt status will be set, and returns immediately from the selection operation may return a nonzero value, as selectorthe wakeupmethod is called the same.

      I haven't used either of these two kinds of blocking (too unpleasant), so I didn't write code to test, and I would test when I encountered it.

      In addition to the above cases, the interrupt status of the thread will be set in other cases.

reference

  • Java Core Technology Volume 1 Chapter 12
  • Java8 API

Guess you like

Origin blog.csdn.net/qq_41512783/article/details/108943193