你真的懂 Thread.interrupt 了吗?

本文详细探讨了Java中Thread.interrupt()方法的工作原理。通过实例展示了该方法并不直接停止线程,而是设置中断标志。线程在阻塞状态如sleep时,interrupt会抛出InterruptedException,允许程序捕获并决定后续行为。文章总结了如何利用中断状态进行线程控制,包括在异常处理中再次中断以终止线程。
摘要由CSDN通过智能技术生成

目录

前言

看了下面这几个例子你就全懂了

总结


前言

        interrupt 这个单词有打断,中断的意思,可是当调用 Thread.interrupt 就会让一个运行着的线程立刻停止吗?答案是否定的,本篇文章就来看下它到底有什么用吧?

看了下面这几个例子你就全懂了

public class InterruptTest {
    public static void main(String[] args) throws InterruptedException {
        Thread td = new Thread(new Runnable() {
            @Override
            public void run() {
                int count = 0;
                while (true) {
                    boolean interrupted = Thread.currentThread().isInterrupted();
                    System.out.println(Thread.currentThread() + "线程是否处于中断状态" + interrupted);
                    if (interrupted) {
                        System.out.println(Thread.currentThread() + "虽然我被中断了,但是我还是能继续执行~");
                        count++;
                    }
                    if (count == 2) {
                        System.out.println("我想停止这个线程的任务了");
                        break;
                    }
                }

            }
        });
        td.start();
        System.out.println(Thread.currentThread() + "调用 interrupt 方法之前: " + td.isInterrupted());
        td.interrupt();
        System.out.println(Thread.currentThread() + "调用 interrupt 方法之后: " + td.isInterrupted());
    }
}

//执行结果
Thread[main,5,main]调用 interrupt 方法之前: false
Thread[main,5,main]调用 interrupt 方法之后: true
Thread[Thread-0,5,main]线程是否处于中断状态true
Thread[Thread-0,5,main]虽然我被中断了,但是我还是能继续执行~
Thread[Thread-0,5,main]线程是否处于中断状态true
Thread[Thread-0,5,main]虽然我被中断了,但是我还是能继续执行~
我想停止这个线程的任务了

        从样例可以看到当 Thread.interrupt() 执行之后,只是将该线程的中断状态标记为 true。线程的并不会影响线程任务的执行,从执行结果也可以看出来,只有我手动 break 之后才将任务给停了下来,而跟 interrupt 无关。

        那么这个机制有什么用呢?下面再看下一个例子

public class InterruptTest {
    public static void main(String[] args) throws InterruptedException {
        Thread td = new Thread(new Runnable() {
            @Override
            public void run() {
                boolean interrupted = Thread.currentThread().isInterrupted();
                while (!interrupted) {
                    System.out.println(Thread.currentThread() + "线程是否处于中断状态" + interrupted);
                    interrupted = Thread.currentThread().isInterrupted();
                }

            }
        });
        td.start();
        System.out.println(Thread.currentThread() + "调用 interrupt 方法之前: " + td.isInterrupted());
        td.interrupt();
        System.out.println(Thread.currentThread() + "调用 interrupt 方法之后: " + td.isInterrupted());
    }
}

// 执行结果
Thread[main,5,main]调用 interrupt 方法之前: false
Thread[Thread-0,5,main]线程是否处于中断状态false
Thread[main,5,main]调用 interrupt 方法之后: true

        看到这里你应该明白了,就是可以利用这个机制使用别的线程来控制当前线程的任务的开始或者结束,或者根据 interrupt 状态来执行不同的代码逻辑。

        当线程出于阻塞情况下,比如调用了 Object.wait, Thread.sleep, Thread.join 等方法之后处在阻塞状态下,如果此时调用了 Thread.interrupt 方法,这个时候会抛出一个异常,如下例

        

public class InterruptTest {
    public static void main(String[] args) throws InterruptedException {
        Thread td = new Thread(new Runnable() {
            @Override
            public void run() {
                boolean interrupted = Thread.currentThread().isInterrupted();
                while (!interrupted) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        System.out.println("捕捉到异常" + e.toString());
                    }
                    System.out.println(Thread.currentThread() + "线程是否处于中断状态" + interrupted);
                    interrupted = Thread.currentThread().isInterrupted();
                }

            }
        });
        td.start();
        System.out.println(Thread.currentThread() + "调用 interrupt 方法之前: " + td.isInterrupted());
        td.interrupt();
        System.out.println(Thread.currentThread() + "调用 interrupt 方法之后: " + td.isInterrupted());
    }
}

//执行结果
Thread[main,5,main]调用 interrupt 方法之前: false
Thread[main,5,main]调用 interrupt 方法之后: false
捕捉到异常java.lang.InterruptedException: sleep interrupted
Thread[Thread-0,5,main]线程是否处于中断状态false
Thread[Thread-0,5,main]线程是否处于中断状态false
Thread[Thread-0,5,main]线程是否处于中断状态false
Thread[Thread-0,5,main]线程是否处于中断状态false
Thread[Thread-0,5,main]线程是否处于中断状态false
Thread[Thread-0,5,main]线程是否处于中断状态false
。。。程序没有停止,会一直打印 “Thread[Thread-0,5,main]线程是否处于中断状态false”

        从这个例子中可以看到,当线程在睡觉的时候调用它的 interrupt 方法,会抛出一个 java.lang.InterruptedException 类型的异常,这是因为 sleep 等阻塞方法会检查 interrupt 状态,如果它被修改为 true 了,就会抛出异常。

        可是从执行结果来看,当执行完 interrupt() 方法之后再次查看中断状态,结果还是 false, 且线程的任务还在一直执行并不会停下来,相当于是把人家叫醒继续干活。这是因为 sleep 等阻塞方法还会把 interrupt 状态给改回去,然后再抛出异常,所以检测到的状态还是 false。

        可见此时 interrupt 方法只是把睡觉的线程给叫醒了,那么利用这个机制又能干嘛呢?比如你通过监控觉得某个线程睡得时间太久了,你可以通过该方法把它叫醒然后继续干活,当然再捕捉到异常之后也可以再次调用  interrupt 方法,这样的话可以让线程的任务真正停下来。

public class InterruptTest {
    public static void main(String[] args) throws InterruptedException {
        Thread td = new Thread(new Runnable() {
            @Override
            public void run() {
                boolean interrupted = Thread.currentThread().isInterrupted();
                while (!interrupted) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        System.out.println("捕捉到异常" + e.toString());
                        System.out.println("我确定要中断该线程了~");
                        Thread.currentThread().interrupt();
                    }
                    interrupted = Thread.currentThread().isInterrupted();
                    System.out.println(Thread.currentThread() + "线程是否处于中断状态" + interrupted);
                }

            }
        });
        td.start();
        System.out.println(Thread.currentThread() + "调用 interrupt 方法之前: " + td.isInterrupted());
        td.interrupt();
        System.out.println(Thread.currentThread() + "调用 interrupt 方法之后: " + td.isInterrupted());
    }
}

//执行结果
Thread[main,5,main]调用 interrupt 方法之前: false
Thread[main,5,main]调用 interrupt 方法之后: false
捕捉到异常java.lang.InterruptedException: sleep interrupted
我确定要中断该线程了~
Thread[Thread-0,5,main]线程是否处于中断状态true

总结

        看到这里大家应该都知道了,interrupt() 只是修改一个状态,并不会导致线程立刻停止。但是可以利用该状态结合自己的业务做一些有趣的事情哦~

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值