线程的中断方法 interrupt()、interrupted()、isInterrupted() 的使用介绍

interrupt():非静态方法,修改线程对象的中断标志为true。

interrupted():静态方法,查看并返回当前线程的中断标志,true为中断状态,false为非中断状态。但是源码中给出解释,当第一次调用时返回当前线程状态,并同时将该线程的中断标志复位为false(线程默认状态为false),可与interrupt()方法结合使用。

isInterrupted():非静态方法,查看并返回对应线程对象的中断标志。

上面三个方法与stop()方法不同,stop()方法由于逻辑实现过于强硬,目前几乎已经被弃用(由于强行结束线程导致一些业务代码无法正常执行,比如资源释放一类的代码等),而interrupt 的方法配合使用得中断标志,可以让开发者遇到比较费时、费资源的业务代码块时,处理得更加灵活。

来看看interrupted() 和 isInterrupted() 的源码:

interrupted()
isInterrupted()

可以看到都是调用了 native 的 isInterrupted(boolean ClearInterrupted),参数传false,代表返回时修改当前线程中断标志状态;参数传true,代表第一次返回时,同时修改当前线程中断标志为默认值false。所以源码中给出解释,当第二次调用时会清除线程的中断状态


image.png

下面给出一些简单的使用代码:

public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                int i = 1;
                //判断线程中断标志  Thread.interrupted() -> true 代表已中断
                while(!Thread.interrupted()){
                    System.out.println("线程 i:" + i);
                    i++;
                }
                //循环结束打印中断标志
                System.out.println("Thread.interrupted():" + Thread.interrupted()); 
            }
        });
        System.out.println("thread start!");
        thread.start();
        try {
            sleep(10);  //主线程睡眠10毫秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("thread interrupt"); 
        thread.interrupt();
        System.out.println("isInterrupted():" + thread.isInterrupted());
    }

输出的结果:


image.png

可以看到 thread.interrupt() 修改了中断标志为true,让线程跳出了循环,随后再次打印Thread.interrupted(),返回为false,代表线程又将中断标志置位了初始的未中断状态。

还有一种使用方法:

public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public synchronized void run() {
                try {
                    System.out.println("当前线程进入wait()方法,线程挂起");
                    wait();
                } catch (InterruptedException e) {
                    //e.printStackTrace();
                    System.out.println("try代码块中抛出InterruptedException异常,跳转到catch继续执行!");
                }
                System.out.println("Thread.interrupted():" + Thread.interrupted());
            }
        });
        System.out.println("thread start!");
        thread.start();
        System.out.println("thread interrupt");
        thread.interrupt();
    }

来看看执行效果:


image.png

配合源码的解释:


image.png

上面简单代码表示,在线程跑到wait()方法挂起时,遇到 interrupt() 方法抛出了一个InterruptedException异常。由于stop()方法几乎已经被抛弃,所以当我们使用interrupt() 方法时,需要结合实际的业务逻辑来完善正常中断和阻塞异常的处理情况。

你可能感兴趣的:(线程的中断方法 interrupt()、interrupted()、isInterrupted() 的使用介绍)