首页 > 其他分享 >线程池子线程的终止Shutdown()、ShutdownNow()

线程池子线程的终止Shutdown()、ShutdownNow()

时间:2023-03-18 17:46:50浏览次数:38  
标签:状态 ShutdownNow Thread 中断 线程 Shutdown interrupt 方法

背景

之前某需求在触发流控时需要中断ExcutorService中的子线程,发现无论Shutdown、ShutdownNow方法都无法直接停止子线程,今天看到线程的interrupt()方法才了解如何停止。

stop() 和 interrupt()

stop方法

stop() 方法会真的杀死线程,不给线程喘息的机会,如果线程持有 ReentrantLock 锁,被 stop() 的线程并不会自动调用 ReentrantLock 的 unlock() 去释放锁,那其他线程就再也没机会获得 ReentrantLock 锁,类似的方法还有 suspend() 和 resume() 方法。故已不建议使用。

interrupt方法

interrupt() 方法仅仅是通知线程,线程有机会执行一些后续操作,同时也可以无视这个通知。

被 interrupt 的线程,是怎么收到通知的呢?一种是异常,另一种是主动检测。

异常

  • 当线程 A 处于 WAITING、TIMED_WAITING 状态时,如果其他线程调用线程 A 的 interrupt() 方法,会使线程 A 返回到 RUNNABLE 状态,同时线程 A 的代码会触发 InterruptedException 异常

  • 当线程 A 处于 RUNNABLE 状态时,并且阻塞在IO上时。如阻塞在java.nio.channels.InterruptibleChannel 上时,如果其他线程调用线程 A 的 interrupt() 方法,线程 A 会触发 java.nio.channels.ClosedByInterruptException 这个异常;而阻塞在 java.nio.channels.Selector 上时,如果其他线程调用线程 A 的 interrupt() 方法,线程 A 的 java.nio.channels.Selector 会立即返回。

tips: 这里的状态为Java线程状态:NEW(初始化状态)RUNNABLE(可运行 / 运行状态)BLOCKED(阻塞状态)WAITING(无时限等待)TIMED_WAITING(有时限等待)TERMINATED(终止状态)

主动检查

线程处于 RUNNABLE 状态,并且没有阻塞在某个 I/O 操作上,得依赖线程 A 主动检测中断状态。

如果其他线程调用线程 A 的 interrupt() 方法,那么线程 A 可以通过 isInterrupted() 方法,检测是不是自己被中断。

public class Main {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            for (int i = 0; i < 10000000; i++) {
                System.out.println(i);
                if (Thread.currentThread().isInterrupted()) {
                    System.out.println("find Interrupted");
                    break;
                }
            }
        });
        ExecutorService executors = Executors.newFixedThreadPool(1);
        // 线程池执行
        System.out.println("excute");
        executors.execute(t);
        // 等待0.5秒
        Thread.sleep(500);
        // 线程池中断
        executors.shutdownNow();
        t.join();
    }
}

如果子线程不检测isInterrupted()并主动停止,那么会继续运行下次。

中断标记与清楚

interrupt()会给对象线程打上中断标记,而捕获InterruptedException异常会清除标记。

Thread.currentThread().isInterrupted()不会清除标记。

shutdown()和shutdownNow()

shutdown方法只会取消等待中的任务,而shutdownNow方法还会给执行中的任务打上中断标记。

标签:状态,ShutdownNow,Thread,中断,线程,Shutdown,interrupt,方法
From: https://www.cnblogs.com/kiper/p/17231281.html

相关文章

  • 为什么不能使用Executors创建线程池
    ExrcutorExecutors是一个Java中的工具类。提供工厂方法来创建不同类型的线程池。如下所示:newFixedThreadPool(intnThreads):创建固定数目线程的线程池。newCachedThrea......
  • JAVA线程锁基础
    https://blog.csdn.net/qq_33375499/article/details/105161343Synchnized和lock的区别Synchronized是悲观锁CAS是乐观锁 锁的状态 无锁->偏向锁->轻量级锁->......
  • 多线程基础
     基本概念:程序、进程、线程程序(program):为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象。进程(process):是指一个内存中运行......
  • 线程池中阻塞队列的作用?为什么是先添加列队而不是先创建最大线程?
    线程池中阻塞队列的作用:1.⼀般的队列只能保证作为⼀个有限⻓度的缓冲区,如果超出了缓冲⻓度,就⽆法保留当前的任务了,阻塞队列通过阻塞可以保留住当前想要继续⼊队的任务。2.......
  • c++ 影响多线程速度的因素记录
    目录0.序言1.缓存行同步问题/共享数据竞争1.1测试代码1.2测试逻辑1.3测试结果1.4小结2.任务颗粒度过小问题2.1测试代码2.1测试逻辑2.2测试结果2.3小结3.缓存未......
  • 谈谈线程间的协作(wait/notify/sleep/yield/join)
    线程的状态Java中线程中状态可分为五种:New(新建状态),Runnable(就绪状态),Running(运行状态),Blocked(阻塞状态),Dead(死亡状态)。New:新建状态,当线程创建完成时为新建状态,即newThread......
  • 线程间通信
    参考:https://zhuanlan.zhihu.com/p/452313580https://zhuanlan.zhihu.com/p/34362413https://zhuanlan.zhihu.com/p/151289085https://www.cnblogs.com/bearbrick0/p/1......
  • 为什么用线程池?解释一下线程池参数?
    1、降低资源消耗;提高线程利用率,降低创建和销毁线程的消耗。2、提高响应速度;任务来了,直接有线程可用可执行,而不是先创建线程,再执行3、提高线程的可管控性;线程是稀缺资源,使......
  • 为什么用线程池?解释一下线程池参数?
    1、降低资源消耗;提高线程利用率,降低创建和销毁线程的消耗。2、提高响应速度;任务来了,直接有线程可用可执行,而不是先创建线程,再执行3、提高线程的可管控性;线程是稀缺资源,使......
  • 谈谈ConcurrentHashMap是如何保证线程安全的?
    jdk1.7中是采用Segment+HashEntry+ReentrantLock的方式进行实现的,而1.8中放弃了Segment臃肿的设计,取而代之的是采用Node+CAS+Synchronized来保证并发安全进行实现......