当前位置: 首页 > news >正文

ThreadPoolExecutor 任务的中断状态是否会影响后续任务

ThreadPoolExecutor 任务的中断状态是否会影响后续任务

    • 实验
    • 从源码中找原因
    • 总结

在使用线程池时,如果调用 future.cancel(true) 会中断工作线程。如果被取消的任务没有处理中断状态,即没有调用类似 Thread.sleep() 等会抛出 InterruptedException 异常的方法,又没有通过 Thread.interrupted() 清除中断状态,那中断状态可能会被同一个工作线程执行的下一个任务捕捉到,进而导致任务被莫名其妙的中断。

实验

为了验证中断状态是否会影响后续任务有又以下测试代码。

  • 使用单线程的线程池保证任务都是在一个线程中执行。
  • 提交两个任务,并打印中断状态
    • 第一个任务是简单的 for 循环,在任务开始执行后 500ms 调用 future1.cancel(true) 中断任务1。
    • 等待任务 1 执行完成后再提交任务 2,任务 2 执行 Thread.sleep(10 * 1000),如果中断状态能被任务 2 捕捉到,则会中断 sleep() 并打印 “线程被中断”。
package com.example.jdk8;import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.*;@Slf4j
public class Test {public static void main(String[] args) throws InterruptedException {// 单线程的线程池ExecutorService executor = Executors.newSingleThreadExecutor();Future<?> future1 = executor.submit(() -> {log.info("任务 1 开始, 中断状态: {}", Thread.currentThread().isInterrupted());// 运行时间超过 500msfor (int i = 0; i < 10000000; i++) {Thread.yield();}log.info("任务 1 结束, 中断状态: {}", Thread.currentThread().isInterrupted());});Thread.sleep(500);future1.cancel(true);log.info("任务取消状态: {}", future1.isCancelled());// 等待任务 1 执行完成后再提交任务 2Thread.sleep(5 * 1000);log.info("提交任务 2");executor.execute(() -> {log.info("任务 2 开始, 中断状态: {}", Thread.currentThread().isInterrupted());try {Thread.sleep(10 * 1000);} catch (InterruptedException e) {log.info("线程被中断");}log.info("任务 2 结束, 中断状态: {}", Thread.currentThread().isInterrupted());});executor.shutdown();executor.awaitTermination(1000, TimeUnit.SECONDS);}
}

两个任务的执行线程都是 pool-1-thread-1,第三行任务 1 结束时的中断状态是 true,但任务 2 打印的中断状态都是 false,说明中断状态不会影响后续任务。

16:45:29.815 [pool-1-thread-1] INFO com.example.jdk8.Test -- 任务 1 开始, 中断状态: false
16:45:30.329 [main] INFO com.example.jdk8.Test -- 任务取消状态: true
16:45:33.464 [pool-1-thread-1] INFO com.example.jdk8.Test -- 任务 1 结束, 中断状态: true
16:45:35.330 [main] INFO com.example.jdk8.Test -- 提交任务 2
16:45:35.330 [pool-1-thread-1] INFO com.example.jdk8.Test -- 任务 2 开始, 中断状态: false
16:45:45.343 [pool-1-thread-1] INFO com.example.jdk8.Test -- 任务 2 结束, 中断状态: false

从源码中找原因

任务 1 结束时的中断状态是 true,但任务 2 的中断状态都是 false,说明在中间某个环境中断状态被重置了。

下面是 ThreadPoolExecutor.runWorker() 方法的源码, while 循环是工作线程的核心逻辑,不断在阻塞队列中 getTask(),然后 task.run()。在第 10、11 行有重要的注释:如果线程池正在关闭,要确保线程被中断;如果不是的话,要确保线程没有被中断。测试代码中的线程池状态是正常运行的,满足第 11 行注释的情况。

runStateAtLeast(ctl.get(), STOP) 为 false,所以会走到 (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP))Thread.interrupted() 会返回当前的中断状态并将中断状态重置为 false,所以任务 2 打印的中断状态为 false。

final void runWorker(Worker w) {Thread wt = Thread.currentThread();Runnable task = w.firstTask;w.firstTask = null;w.unlock(); // allow interruptsboolean completedAbruptly = true;try {while (task != null || (task = getTask()) != null) {w.lock();// If pool is stopping, ensure thread is interrupted;// if not, ensure thread is not interrupted.  This// requires a recheck in second case to deal with// shutdownNow race while clearing interruptif ((runStateAtLeast(ctl.get(), STOP) ||(Thread.interrupted() &&runStateAtLeast(ctl.get(), STOP))) &&!wt.isInterrupted())wt.interrupt();try {beforeExecute(wt, task);try {task.run();afterExecute(task, null);} catch (Throwable ex) {afterExecute(task, ex);throw ex;}} finally {task = null;w.completedTasks++;w.unlock();}}completedAbruptly = false;} finally {processWorkerExit(w, completedAbruptly);}
}

总结

被同一工作线程执行的任务,前面任务的中断状态不会影响后续任务,因为在执行任务前会调用 Thread.interrupted() 将中断状态重置为 false。

http://www.dtcms.com/a/615844.html

相关文章:

  • 加查网站建设常德地区网站建设
  • 哪个网站网站空间最好传媒类网站模板
  • 网络营销论文选题方向做搜狗手机网站优化排
  • 西安做网站缑阳建php做网站后台
  • 昆明网站制作报价安卓手机网页视频怎么下载
  • AI入门系列之RAG高效召回方法实践指南:从调参到部署的全流程实战手册
  • 哈希表有哪些算法?
  • 陕西外贸英文网站建设快速的网站设计制作
  • 做神马网站优化排名官网招聘平台
  • 米拓做的网站如何改代码网站刚建好怎么做能让百度收录
  • 判断网站cms上海自助模板建站
  • 大连六兄弟网站建设做捐款网站
  • 免费制作购物网站小程序商城的运营模式
  • 基于springboot火锅店管理系统【带源码和文档】
  • 桂林餐饮兼职网站建设网站建设推荐公司
  • 关键词挖掘站长ih5专业的h5制作工具
  • 哪个网站可以做制图兼职西安做网站哪里好
  • 设计师的素材网站seo优化博客
  • 宠物用品网站建设网站续费自己做
  • 课程设计代做网站php制作网页怎么制作
  • 网站广告联盟平台如何建设网站兴田德润可信赖
  • 聊城做网站费用价位wordpress模版安装
  • 示范校建设验收网站不重名的建筑公司名字
  • 网站 开发逻辑个人网站能挂广告吗
  • 贵阳市城乡建设厅网站网站开发后台指什么
  • 一个网站页面设计多少钱教人做美食的网站
  • 钢管网站建设网站百度知道
  • 公司网站建设一定要求原图吗wordpress 下单
  • 网站更新的意义个人网站放什么内容
  • 查找使用wordpress的网站十大广告联盟