Java实现终止线程池中正在运行的定时任务

2023-05-16

贴个广告

楼主的博客已全部搬迁至自己的博客,感兴趣的小伙伴请移步haifeiWu与他朋友们的博客专栏

源于开发

最近项目中遇到了一个新的需求,就是实现一个可以动态添加定时任务的功能。说到这里,有人可能会说简单啊,使用quartz就好了,简单粗暴。然而quartz框架太重了,小项目根本不好操作啊。当然,也有人会说,jdk提供了timer的接口啊,完全够用啊。但是我们项目的需求完全是多线程的模型啊,而timer是单线程的,so,楼主最后还是选择了jdk的线程池。

线程池是什么

Java通过Executors提供四种线程池,分别为:
newCachedThreadPool :创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool : 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool : 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor : 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

楼主项目中用到的是newScheduledThreadPool, 就这些吧,再多的楼主就班门弄斧了,Google一下,一大堆。

线程池service的获取

楼主通过单例模式来获取线程池的service,代码如下:

/**
 * 线程池创建.
 * @author wuhf
 * @date 2018/01/16
 */
public class ThreadPoolUtils {

    private static ScheduledExecutorService executorService;

    private ThreadPoolUtils() {
        //手动创建线程池.
        executorService = new ScheduledThreadPoolExecutor(10,
                new BasicThreadFactory.Builder().namingPattern("syncdata-schedule-pool-%d").daemon(true).build());
    }

    private static class PluginConfigHolder {
        private final static ThreadPoolUtils INSTANCE = new ThreadPoolUtils();
    }

    public static ThreadPoolUtils getInstance() {
        return PluginConfigHolder.INSTANCE;
    }

    public ScheduledExecutorService getThreadPool(){
        return executorService;
    }

}

中断某一个正在运行的线程代码实现

废话就不多说了,代码如下:

/**
 * 中断线程池的某个任务.
 */
public class InterruptThread implements Runnable {

    private int num;

    public InterruptThread (int num){
        this.num = num;
    }

    public static void main(String[] args) throws InterruptedException {

        Thread interruptThread = new Thread(new InterruptThread(1));
        ScheduledFuture<?> t = ThreadPoolUtils.getInstance().getThreadPool().scheduleAtFixedRate(interruptThread,0,2,
                TimeUnit.SECONDS);

        InterruptThread interruptThread1 = new InterruptThread(2);
        ThreadPoolUtils.getInstance().getThreadPool().scheduleAtFixedRate(interruptThread1,0,2,
                TimeUnit.SECONDS);

        InterruptThread interruptThread2 = new InterruptThread(3);
        ThreadPoolUtils.getInstance().getThreadPool().scheduleAtFixedRate(interruptThread2,0,2,
                TimeUnit.SECONDS);
        Thread.sleep(5000);

        //终止正在运行的线程interruptThread
        t.cancel(true);
        while (true){

        }
    }

    @Override
    public void run() {
        System.out.println("this is a thread" + num);
    }
}

踩坑记录

楼主在使用如下代码时,突然想到当这个定时任务需要被停止时该如何停止线程运行

ThreadPoolUtils.getInstance().getThreadPool().scheduleAtFixedRate(interruptThread,0,2,
                TimeUnit.SECONDS);

既然我有这样的需求,那就Google一下吧,找了大半圈,愣是没找到相关资料,都是一些关于Java线程池的深入分析。或者是全局变量啥的,并没有找到令楼主满意的解决方案。

既然没有线程的那就扒一下scheduleAtFixedRate的底层源码看看是什么东西吧,果不其然我在源码中看到了scheduleAtFixedRate方法的具体实现,发现他的返回值是ScheduledFuture。

 public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,
                                                  long initialDelay,
                                                  long period,
                                                  TimeUnit unit) {
        if (command == null || unit == null)
            throw new NullPointerException();
        if (period <= 0)
            throw new IllegalArgumentException();
        ScheduledFutureTask<Void> sft =
            new ScheduledFutureTask<Void>(command,
                                          null,
                                          triggerTime(initialDelay, unit),
                                          unit.toNanos(period));
        RunnableScheduledFuture<Void> t = decorateTask(command, sft);
        sft.outerTask = t;
        delayedExecute(t);
        return t;
    }

接着往下我们再看看ScheduledFuture里面有什么东西吧,没有让楼主失望,看到了这个

public boolean cancel(boolean mayInterruptIfRunning) {
            boolean cancelled = super.cancel(mayInterruptIfRunning);
            if (cancelled && removeOnCancel && heapIndex >= 0)
                remove(this);
            return cancelled;
}

//从线程的运行队列中移除当前线程
public boolean remove(Runnable task) {
        boolean removed = workQueue.remove(task);
        tryTerminate(); // In case SHUTDOWN and now empty
        return removed;
}

再往上查super.cancel(mayInterruptIfRunning)是什么东西,我们看到了这个,

//通过调用线程的interrupt方法终止线程运行
public boolean cancel(boolean mayInterruptIfRunning) {
        if (!(state == NEW &&
              UNSAFE.compareAndSwapInt(this, stateOffset, NEW,
                  mayInterruptIfRunning ? INTERRUPTING : CANCELLED)))
            return false;
        try {    // in case call to interrupt throws exception
            if (mayInterruptIfRunning) {
                try {
                    Thread t = runner;
                    if (t != null)
                        t.interrupt();
                } finally { // final state
                    UNSAFE.putOrderedInt(this, stateOffset, INTERRUPTED);
                }
            }
        } finally {
            finishCompletion();
        }
        return true;
    }

到这里所有的问题都迎刃而解。

总结一下吧

项目中总是会遇到比较难搞的解决方案,当Google不太好找时,翻一下jdk的源码或许也是一个不错的方法。

参考文章

  • Java实现终止线程池中正在运行的定时任务)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java实现终止线程池中正在运行的定时任务 的相关文章

  • 2023RSAC创新沙盒大赛十强公布,软件供应链与开源软件安全再成焦点

    近日 xff0c 2023RSAC大会公布了第18届RSAC创新沙盒竞赛的决赛 十强企业 软件安全企业Endor Labs成功入围 xff0c 软件供应链安全和开源安全问题再次成为国际焦点 Endor Labs提供了一个可依赖的生命周期管理
  • 如何找到现有研发体系的「内耗问题」?| 谈效风生

    第3期 xff1a 如何找到现有研发体系的 内耗问题 xff1f 在上一期 谈到提升效能 xff0c 我们应该如何下手 xff1f 我们聊到开始做研发效能的四个要点 xff1a 评估现有流程 引入自动化工具 建立度量指标 持续改进 本期就围
  • Ubuntu 18之vnc连接不上问题(已解决)

    在配置vnc时所以的准备动作已经准备好了 xff0c 该配的文件也配好了 xff0c 但就是一直连接不上 在主机端报time out的错误 xff0c 后来查百度得知vncserver xff1a 1对应5901端口 xff0c 2就是59
  • 「自动化」聊起来简单,做起来难 | 谈效风生

    第4期 xff1a 自动化 聊起来简单 xff0c 做起来难 在上一期 如何找到现有研发体系的 内耗问题 中 xff0c 我们聊了评估现有研发体系 xff0c 正确的找到 体系内耗问题 xff0c 是改变研发体系的第一步 本期我们继续聊下一
  • GitChat·前端 | 从软件工程角度看大前端技术栈

    GitChat 作者 xff1a 韩亦乐 前言 我们都知道 xff0c 大学几乎是没有 Web 前端课的 以我所在的大学为例 xff0c 唯一引导我们了解 JavaScript 的也只是 人机界面 和 Web应用开发 选修课 再者 xff0
  • 当我说要做大数据工程师时他们都笑我,直到三个月后……

    作者 xff1a Fickr孫啟誠 原文 xff1a 三个月大数据研发学习计划实战解析 关注微信公众号 xff1a GitChat 技术杂谈 一本正经的讲技术 不要错过文末彩蛋 申明 xff1a 本文旨在为普通程序员 xff08 Java程
  • 原来这样做,才能向架构师靠近

    说在前面 xff1a 达人课是GitChat的一款轻阅读产品 xff0c 由特约讲师独家发布 每一个课程你都可获得6 12篇的深度文章 xff0c 同时可在读者圈与讲师互动交流 GitChat达人课 xff0c 让技术分享更简单 进入我的G
  • 带你从零开始,快速学会 Matlab GUI

    本文来自作者 木木小迷哥 在 GitChat 上分享 Matlab GUI 零基础学员快速入门 xff0c 阅读原文 查看交流实录 文末高能 编辑 洛肯 Matlab广泛地应用于数学分析 计算 自动控制 系统仿真 数字信号处理 图像处理 数
  • Cordova App 打包全揭秘

    运营专题 零预算引爆个人和企业品牌 原文链接 Selenium 自动化测试从零实战 原文链接 原来这样做 xff0c 才能向架构师靠近 原文链接 TensorFlow on Android xff1a 物体识别 原文链接 TensorFlo
  • Selenium 自动化测试从零实战

    运营专题 零预算引爆个人和企业品牌 原文链接 原来这样做 xff0c 才能向架构师靠近 原文链接 Cordova App 打包全揭秘 原文链接 TensorFlow on Android xff1a 物体识别 原文链接 TensorFlow
  • [运营专题]零预算引爆个人和企业品牌

    文章推荐 Selenium 自动化测试从零实战 原文链接 原来这样做 xff0c 才能向架构师靠近 原文链接 Cordova App 打包全揭秘 原文链接 TensorFlow on Android xff1a 物体识别 原文链接 Tens
  • 图解敏捷教练和 ScrumMaster

    运营专题 零预算引爆个人和企业品牌 原文链接 Selenium 自动化测试从零实战 原文链接 原来这样做 xff0c 才能向架构师靠近 原文链接 Cordova App 打包全揭秘 原文链接 TensorFlow on Android xf
  • TensorFlow on Android:物体识别

    运营专题 零预算引爆个人和企业品牌 原文链接 Selenium 自动化测试从零实战 原文链接 原来这样做 xff0c 才能向架构师靠近 原文链接 Cordova App 打包全揭秘 原文链接 TensorFlow on Android xf
  • Jetson Xavier NX can通信,拒绝误导!

    概述 最近在开发一个网关项目 xff0c 需要调试一些通信接口 网关底板是基于jetson xavier nx设计的 xff0c 所以硬件上许多相似 xff0c 所以我也会基于jetson xavier nx去做一些接口的测试 xff0c
  • TensorFlow on Android:训练模型

    文章推荐 运营专题 零预算引爆个人和企业品牌 原文链接 Selenium 自动化测试从零实战 原文链接 原来这样做 xff0c 才能向架构师靠近 原文链接 Cordova App 打包全揭秘 原文链接 TensorFlow on Andro
  • 深入理解 MySQL 底层实现

    本文来自作者 默默 在 GitChat 上分享 深入理解 MySQL 底层实现 xff0c 阅读原文 查看交流实录 文末高能 编辑 哈比 MySQL 的常用引擎 1 InnoDB InnoDB 的存储文件有两个 xff0c 后缀名分别是 f
  • 修改订单金额!?0.01 元购买 iPhoneX?| Web谈逻辑漏洞

    本文来自作者 肖志华 在 GitChat 上分享 Web 安全恩仇录 xff1a 再谈逻辑漏洞 xff0c 阅读原文 查看交流实录 文末高能 编辑 哈比 Web 漏洞里有 SQL 注入 XSS 等漏洞 xff0c 但是逻辑漏洞等问题也是一个
  • 如何开发一款游戏:游戏开发流程及所需工具

    本文来自作者 goto先生 在 GitChat 上分享 如何开发一款游戏 xff1a 游戏开发流程及所需工具 编辑 哈比 游戏作为娱乐生活的一个方面 xff0c 参与其中的人越来越多 xff0c 而大部分参与其中的人都是以玩家的身份 他们热
  • 如何用 Python 做自动化测试

    本文来自作者 Vant 在 GitChat 上分享 如何用 Python 做自动化测试 编辑 哈比 一 Selenium 环境部署 1 window 环境部署 1 1 当前环境 Win10 64 位系统 xff1b Python3 6 2
  • 我真的要做一辈子的程序员吗?

    本文来自作者 王鹏 在 GitChat 上分享 程序员跳槽时 xff0c 如何正确做好职业规划 xff1f 阅读原文 查看交流实录 编辑 贝吉塔 经常听一些同学说 xff1a 不知道下一份工作该去哪类公司做些什么 xff0c 我的职场人际一

随机推荐

  • 20万到100万年薪的算法工程师有什么区别?

    公元七世纪 xff0c 在车迟国国家气象局组织的一次求雨活动中 xff0c 虎力 鹿力 羊力三位大仙成功地祈下甘霖 xff0c 救黎民于水火中 老国王虽然不明就里 xff0c 却从此尊他们为国师 xff0c 奉道教为圭臬 本世纪 xff0c
  • 在win7下安装ubuntu

    安装VMware 从官网下载VMware workstation full 10 0 4 2249910 exe文件 xff0c 一直点击下一步 xff0c 直到安装成功 安装成功的界面如图所示 xff1a 安装Ubuntu 1 获取发行版
  • 带参数的宏定义 #define

    main c C语言学习 include lt stdio h gt 求和函数 int sum int v1 int v2 return v1 43 v2 宏定义 define 代表要定义一个宏 SUM 宏的名称 v1 v2 参数 xff0
  • 串口编程项目— PX4FLOW 传感器数据接收处理(英文paper直接贴过来)

    写在前面 xff1a 七月份初 xff0c 结束交流生项目 xff0c 向导师申请了个项目 xff0c 关于PX4FLOW传感器的 xff0c serial programming 的java编程 xff0c 下午刚刚提交完paper 写个
  • 电路城(www.cirmall.com)-基于HS1101LF和TC1047A 温湿度传感器模块(硬件+源码+设计说明等)

    电路城 xff08 www cirmall com xff09 本次分享的温湿度传感器模块采用瑞萨电子生产的 R7F0C802 单片机作为控制单元 xff0c 采集温度传感器 TC1047A 输出的电压信号和湿度传感器HS1101LF 电路
  • 服务器后端开发,学什么编程语言?

    服务器后端开发 xff0c 学什么编程语言 xff1f 技术 后台开发 xff0c 目前主流的编程语言是Java xff0c Go语言 xff0c C 43 43 xff0c python 以及php 个人建议学Java xff0c 主流中
  • ROS基础:功能包的创建与编译

    创建 如果你使用的是catkin编译系统 xff0c 那么可以很容易地创建一个功能包 首先进入你的工作空间的src目录下 xff1a cd catkin ws src 然后运行catkin create pkg命令 xff1a catkin
  • 关于TF转换信息(Transforms)的理解

    本文主要内容参考自ROS wiki tf Overview Transformations xff0c 在加入了自己的一些理解的同时 xff0c 我也对原文进行了适当的修改 原文使用Creative Commons Attribution
  • RealSense SDK 开发笔记(一)环境配置

    转载请注明出处 2017 以后的SDK结构必然趋于稳定 xff0c 也就会多一些新特性和新设备的支持 xff0c 配置流程不再变化 2016 2 xff1a 目前SDK版本是2016R1 xff0c 配置过程一模一样 xff0c SDK主要
  • 闭包方法的学习

    相关链接 swift中使用 64 noescape的正确姿势 文档闭包 闭包可以捕获和存储其在上下文中任意常量和变量的引用 被称为包裹常量和变量 Swift会为你管理在捕获过程中涉及到的所有内存操作 在函数章节中介绍的全局和嵌套函数也是特殊
  • CMakeLists常用方法

    我们在编译一个C C 43 43 项目时有时候是需要我们阅读编译脚本来确定编译时的参数 CMakeLists txt是比较常见的编译脚本 xff0c 这里简单介绍几个常用的函数 cmake minimum required 设置cmake的
  • halcon中Image的像素类型

    在学习halcon算子sub image ImageMinuend ImageSubtrahend ImageSub Mult Add 时 xff0c 在样例中遇到了一个操作 This example demonstrates how to
  • GitHub Action构建并推送DockerHub

    前言 偶尔会构建一些自己用的容器 xff0c 之前一直用的是Docker提供的构建服务 xff0c 然而Docker开始收费了 xff0c 那只能另寻他法 之所以不本地构建推送 xff0c 是因为构建的时候经常因为网络问题 xff0c 访问
  • BIO与NIO的方式实现文件拷贝

    面试题 编程实现文件拷贝 xff08 这个题目在笔试的时候经常出现 xff0c 下面的代码给出了两种实现方案 xff09 span class hljs keyword import span java io FileInputStream
  • 一路(16)走来,一起(17)依然同行

    来个自我介绍吧 xff0c 我叫 xff0c 计算机科学与技术专业 xff0c 本科 xff0c 这句话应该是16年整整一年说过最多的 那么我去年整整一年我又有那些收获呢 xff0c so xff0c 我也来个年终总结 xff0c 年初展望
  • 电路城(www.cirmall.com)-学习IoT,BLE编程绝佳平台,nRF52832 BLE(蓝牙低能耗)开发板

    该nRF52832 BLE xff08 蓝牙低能耗 xff09 开发板是一款具有温度 xff0c 湿度 xff0c 环境光和加速度传感器的蓝牙低能耗开发板 该蓝牙开发板具有ARM Cortex M4F CPU的nRF52832 BLE So
  • Linux上jmeter-server启动失败

    贴个广告 楼主的博客已全部搬迁至自己的博客 xff0c 感兴趣的小伙伴请移步haifeiWu与他朋友们的博客专栏 Jmeter server启动失败 xff1a Cannot start Unable to get local host I
  • Mysql的七种join

    对于SQL的Join xff0c 在学习起来可能是比较乱的 我们知道 xff0c SQL的Join语法有很多inner的 xff0c 有outer的 xff0c 有left的 xff0c 有时候 xff0c 对于Select出来的结果集是什
  • shell脚本实现自动保留最近n次备份记录

    贴个广告 楼主的博客已全部搬迁至自己的博客 xff0c 感兴趣的小伙伴请移步haifeiWu与他朋友们的博客专栏 项目中出现的问题 某天上午服务器出现卡顿特别严重 xff0c 页面加载速度奇慢 xff0c 并且某些页面刷新出现404的问题
  • Java实现终止线程池中正在运行的定时任务

    贴个广告 楼主的博客已全部搬迁至自己的博客 xff0c 感兴趣的小伙伴请移步haifeiWu与他朋友们的博客专栏 源于开发 最近项目中遇到了一个新的需求 xff0c 就是实现一个可以动态添加定时任务的功能 说到这里 xff0c 有人可能会说