Java多线程【4】interrupt打断线程、两阶段终止模式

系列文章目录

Java多线程【1】synchronized对象锁、内置锁使用
Java多线程【2】Java wait/notify的使用于同步模式保护性暂停
Java多线程【3】同步模式之保护性暂停案例 相亲问题
Java多线程【4】interrupt线程的打断机制、两阶段终止模式
Java多线程【5】异步模式之生产者消费者
Java多线程【6】LockSupport park/unpark原理和使用以及于wait/notify的区别



一、为什么不用stop方法

  • 线程的stop方法可以终止线程,但是是粗暴的终止,无法进行终止之后线程的执行任务。
  • 无法释放终止的线程获取的锁。导致系统死锁等多线程并发问题。

二、打断阻塞状态的线程

1.线程如何主动进入阻塞状态

2.线程的sleep、join方法

sleep和join方法会使线程进入WAITING状态

3.锁对象的wait方法

wait方法会使线程进入WAITING状态

4.LockSupport的part方法

这方法不会抛出InterruptedException错误
part方法会使线程进入WAITING状态

注意:LockSupport的part方法会让线程阻塞,使用interrupt方法会直接结束阻塞,且后续的park方法将不会阻塞线程。而其他的阻塞sleep、join、wait是通过抛出一个InterruptedException错误让线程捕获到。

2、打断线程

注意:打断除LockSupport的part方法阻塞状态的线程,线程的打断标志会被置为false

1.打断sleep

        Thread thread = new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        thread.start();
        TimeUnit.SECONDS.sleep(1);
        thread.interrupt();

2.打断join

		Thread thread = new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(3);
                //停止thread线程,这时主线程调用的thread.join()就会被中断
                Thread.currentThread().interrupt();
                TimeUnit.SECONDS.sleep(3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });


        thread.start();
        try {
            thread.join();
        }catch (InterruptedException e){
            e.printStackTrace();
        }

2.打断wait

  1. 新建线程thread调用lock锁对象的wait方法阻塞
  2. 主线程终止thread,此时thread为阻塞状态,会直接被中断报错。
  		Thread thread = new Thread(() -> {
            try {
                synchronized (lock){
                    lock.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });


        thread.start();
        try {
            //thread的线程的wait()方法就会被中断
            thread.interrupt();
        }catch (InterruptedException e){
            e.printStackTrace();
        }

3.打断park

这个part是LockSupport的方法。也是让线程进入到阻塞状态。
注意:在打断标记为true的时候,再次执行park方法线程就不会被阻塞,只有将打断标记重新设置为false才生效。Thread.interrupted()方法可以线程的打断标记重置为false。

  Thread thread = new Thread(() -> {
            System.out.println("park...");
            LockSupport.park();
            System.out.println("unPark");
        });


        thread.start();
        try {
            TimeUnit.SECONDS.sleep(1);
            thread.interrupt();
        }catch (InterruptedException e){
            e.printStackTrace();
        }

三、打断非阻塞状态的线程(两阶段终止模式)

一个线程能优雅的终止另一个线程,这种模式被称为两阶段终止模式

  1. 新建thread1,thread1获取当前线程,轮询线程的中断状态,中断状态为true直接跳出循环结束线程。
  2. 新建thread2,睡眠10秒后中断thread1。
Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if (Thread.currentThread().isInterrupted()) {
                        System.out.println("线程被打断,业务执行完毕");
                        break;
                    }

                    try {
                        System.out.println("执行业务代码中");
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        //睡眠过程中会导致打断标志被重置为false
                        Thread.currentThread().interrupt();
                    }
                }
            }
        });

        Thread thread2 = new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(5);
                thread.interrupt();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        thread.start();
        thread2.start();
    }

四、总结

  • stop方法的废弃原因。
  • 调用线程的sleep、join方法,使用LockSupport的part方法,锁对象的wait方法会使线程进入到阻塞状态。
  • 线程在LockSupport的part时被中断,会直接退出阻塞。其他的方法会以报错的形式抛出。
  • 中断的处理逻辑是日常生产过程中非常重要的环节。线程的stop方法不推荐的使用一方面是因为会导致线程安全的问题,但最主要还是线程被中断后的业务逻辑无法定义。两阶段终止模式可以有效的解决以上线程中断的各种问题。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王乐乐君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值