线程-interrupt方法详解

我们如何在一个线程中暂停另一个线程的运行?
这里不建议是使用stop方法,使用stop方法虽然可以强行终止正在运行或挂起的线程,但使用stop方法是很危险的。stop 方法会真正杀死线程,如果这时线程锁住了共享资源,那么当它被杀死后就再也没有机会释放锁, 其它线程将永远无法获取锁

我们可以使用interrupt方法。在使用该方式时,它并不会像stop方法那样会中断一个正在运行的线程,而是线程会继续运行下去;但会设置该线程的中断状态,即设置为true,线程会不时地检测这个中断标示位,以判断线程是否应该被中断(中断状态是否为true)

public class test2 {
    public static void main(String[] args) {
        try {
            test2();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    private static void test2() throws InterruptedException {
        Thread t2 = new Thread(()->{
            while(true) {
                Thread current = Thread.currentThread();
                boolean interrupted = current.isInterrupted();
                System.out.println(interrupted);
                //自己来决定是否停止现场的运行
                if(interrupted) {
                    System.out.println(interrupted);
                    break;
                }
            }
        }, "t2");
        t2.start();
        //让主线程睡眠一下
        Thread.sleep(500);
        t2.interrupt();
    }
}

输出结果:
在这里插入图片描述
但是当我们打断阻塞中(sleep,wait,join)的线程会让此线程产生一个InterruptedException异常,结束线程的运行。但如果该异常被线程捕获住,该线程依然可以自行决定后续处理(终止运行,继续运行,做一些善后工作等等),而且这个打断阻塞中的线程是会重置标状态为false

@Slf4j
public class test1 {
    public static void main(String[] args) throws InterruptedException {
        TwoParseTermination twoParseTermination = new TwoParseTermination();
        twoParseTermination.start();
        Thread.sleep(3500);
        twoParseTermination.stop();
    }
}
@Slf4j
class TwoParseTermination {
    private Thread monitor;
    // 启动线程
    public void start() {
        monitor = new Thread(() -> {
            while (true) {
                //拿到当前线程
                Thread thread = Thread.currentThread();
                if(thread.isInterrupted()) { // 调用 isInterrupted拿到标记值 这个不会清除标记
                    System.out.println("料理后事 ...");
                    break;  //终止线程
                } else {
                    try {
                        Thread.sleep(1000);
                        System.out.println("执行监控的功能 ...");
                    } catch (InterruptedException e) {
                        System.out.println("设置打断标记 ...");
                        //因为捕获异常后标记值变成了false,这里再打断一下,就相当于把这个正在运行的线程给打断了,所以这里的标记值又变成了ture,如果这里不重置这个标记值那么这个线程是会一直运行的
                        thread.interrupt();
                        e.printStackTrace();
                    }
                }
            }
        }, "monitor");
        monitor.start();
    }
    // 终止线程
    public void stop() {
        monitor.interrupt();
    }
}

在这里插入图片描述
关于isInterrupted()和Interrupted()方法
这两个方法都可以判断当前线程的打断状态,区别在于:

interrupted()是静态方法,并且会重置当前线程的中断状态(还是false)。而isInterrupted()不会重置当前状态

public class test2 {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(100 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
        thread.interrupt();
        Thread.currentThread().interrupt();
        System.out.println("第一次"+Thread.interrupted());
        System.out.println("第二次"+Thread.interrupted());
    }
}

这里我们interrupt了main线程,调用interrupted()方法就会重置为false
在这里插入图片描述

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值