• Java多线程interrupt、interrupted、isInterrupted详解


    一、概念

    1.1 interrupt方法应用场景

    • 用来打断正在阻塞的线程:sleep/wait/join
    • 打断正常的线程

    1.2 interrupt() 方法

            Thread类的实例方法,其作用是中断此线程(此线程不一定是当前线程,而是指调用该方法的Thread实例所代表的线程),但实际上只是给线程设置一个中断标志,线程仍会继续运行。)作用与正常线程会将中断标记设置为true,但是作用于阻塞线程会将中断标志刷新false(中断标记默认为false,刷新就是重新刷会默认)。

    1.3 interrupted() 方法

            Thread类的静态方法,作用是测试当前线程是否被中断(检查中断标志),返回一个boolean并清除中断状态,第二次再调用时中断状态已经被清除,将返回一个false。

    1.4 isInterrupted() 方法

            Thread类的实例方法,作用是只测试此线程是否被中断,不清除中断状态。

    二、实例

    2.1 打断正常线程,不停止线程

    1. public class ThreadTest {
    2. public static void main(String[] args) throws InterruptedException {
    3. Thread t = new Thread(()->{
    4. while (true){
    5. //让thread线程不断运行
    6. }
    7. });
    8. t.start();
    9. Thread.sleep(1000);//让主线程睡一会
    10. t.interrupt();//打断正在正常运行的thread
    11. System.out.println(t.isInterrupted());
    12. }
    13. }

    程序不会停止

    2.2 打断正常线程,并停止线程

    1. public class ThreadTest {
    2. public static void main(String[] args) throws InterruptedException {
    3. Thread t = new Thread(()->{
    4. while (Thread.currentThread().isInterrupted()){
    5. break;
    6. }
    7. });
    8. t.start();
    9. Thread.sleep(1000);//让主线程睡一会
    10. t.interrupt();//打断正在正常运行的thread
    11. System.out.println(t.isInterrupted());
    12. }
    13. }

    程序停止

    2.3 阻塞线程打断

    作用于阻塞线程会将中断标志刷新false

    1. public static void main(String[] args) throws InterruptedException {
    2. Thread thread1=new Thread(()-> {
    3. try {
    4. Thread.sleep(5000);
    5. } catch (InterruptedException e) {
    6. e.printStackTrace();
    7. }
    8. }
    9. );
    10. thread1.start();
    11. thread1.interrupt();
    12. System.out.println(thread1.isInterrupted());
    13. }

    输出:


            这里我们发现输出的是true!这里不是我们前面的结论,打断阻塞的线程不是刷新打断状态为false吗?这里牵扯到并发于并行的概念,这里从主线程运行,而thread1是主线程下的线程,这里先执行的是interrupt()方法,然后才执行的是sleep方法,所以打断的时候它是正常的线程,打断状态为true。

            如果我们换成下面这些代码则会让thread1先睡眠,后打断,这样就会在睡眠阻塞中被打断那么就会刷新,这样打断位就为false!!

    1. public static void main(String[] args) throws InterruptedException {
    2. Thread thread1=new Thread(()-> {
    3. try {
    4. Thread.sleep(5000);
    5. } catch (InterruptedException e) {
    6. e.printStackTrace();
    7. }
    8. }
    9. );
    10. thread1.start();
    11. Thread.sleep(1000);
    12. thread1.interrupt();
    13. System.out.println(thread1.isInterrupted());
    14. }

            这里我们就是false,因为这里在thread1.interrupt();前让主线程睡一会,让thread1有时间进入到睡眠的状态,这样才会造成我们想要的在睡眠阻塞中打断。

    三、两阶段终止设计模式

            这里涉及到在线程T1里如何就“优雅”的终止线程T2(例如上面在主线程中如何优雅终止线程thread)
            优雅:指的不是直接杀死T2,而是给T2一个料理后事的机会。直接杀死不好,stop方法现在也被废弃,就是不让大家直接杀死线程。

    1. public class Demotest {
    2. public static void main(String[] args) throws InterruptedException {
    3. ThreadMonitor threadMonitor=new ThreadMonitor();
    4. threadMonitor.start();
    5. Thread.sleep(3000);//让主线程睡一会
    6. threadMonitor.stop();
    7. }
    8. }
    9. class ThreadMonitor{
    10. private Thread mnoitor;
    11. //启动被监控的线程
    12. public void start(){
    13. mnoitor=new Thread(()->{
    14. while (true){
    15. Thread nowthread=Thread.currentThread();//获取当前线程
    16. if (nowthread.isInterrupted()){//有被打断则调用stop方法
    17. break;
    18. }
    19. try {
    20. nowthread.sleep(1000);
    21. } catch (InterruptedException e) {
    22. e.printStackTrace();
    23. nowthread.interrupt();//设置打断标志为true
    24. System.out.println("设置了打断标记");
    25. }
    26. }
    27. });
    28. mnoitor.start();
    29. }
    30. //想要停止线程
    31. public void stop(){
    32. mnoitor.interrupt();
    33. }
    34. }


    这里通过监控线程的打断标记来控制线程停止。

  • 相关阅读:
    英码科技“深元智能应用”入选中国电信原子能力业务,携手共同打造AI智能视频分析应用“超能力”!
    CMT2380F32模块开发17-ADC例程
    云计算时代的采集利器
    react中jsx语法
    小程序app手机端Python爬虫实战03-uiautomater2项目初始化
    基于Git和Nginx搭建自己的私人图床,告别图片404
    [题解] 多国语言(2021牛客OI赛前集训营)
    一文掌握 Java8 Stream 中 Collectors 的 24 个操作
    【从后端日志文件中过滤出sql语句】
    Matlab loglog函数
  • 原文地址:https://blog.csdn.net/baidu_35410857/article/details/134328524