最近系统开发时遇到这样一个需求:

该功能执行时间很久,如果运行过程出现错误,也无法将其停止,必须眼睁睁的看着它浪费很久时间,除非停止服务器。

于是,我就想着如何给该功能加上一个“停止”的功能呢?

经过不断的思考和测试,发现思路如此简单,直接上代码!

package com.iamzken.test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; public class ThreadPoolExecutorTest {
//线程池
private static ThreadPoolExecutor pool = new ThreadPoolExecutor(3, 5, 5,
TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10),
new ThreadPoolExecutor.CallerRunsPolicy());
//定义一个线程,相当于父线程
private static Thread t;
//保存线程池中当前所有正在执行任务的活动线程,相当于子线程
private static List<Thread> activeThreads = new ArrayList<Thread>(5);
//根据参数b的值,决定是启动线程还是停止线程
public static void test(boolean b) { if (b) {
System.out.println("start========================================");
//停止父线程,这里使用了Thread类的暴力停止方法stop
t.stop();
//遍历并停止所有子线程,这里使用了Thread类的暴力停止方法stop
//这里一定要把子线程也停止掉,原来以为停止了父线程,子线程就会自动停止,事实证明这是错误的,必须在停止父线程的同时停止掉子线程才能彻底停止掉整个线程
for (int i = 0; i < activeThreads.size(); i++) {
Thread t = activeThreads.get(i);
System.out.println(t.getName());
t.stop();
} System.out.println("stop==========================================");
} else {
//创建父线程
t = new Thread() {
@Override
public void run() {
//创建线程池要执行的两个任务r1和r2。这两个任务都是死循环
Runnable r1 = new Thread() {
@Override
public void run() {
Thread currentThread = Thread.currentThread();
activeThreads.add(currentThread);
int i = 1;
while (true) {
System.out.println(currentThread.getName()+"------------>"+(i++));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Runnable r2 = new Thread() {
@Override
public void run() {
Thread currentThread = Thread.currentThread();
activeThreads.add(currentThread);
int i = 1;
while (true) {
System.out.println(currentThread.getName()+"------------>"+(i++));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
//在线程池中执行两个任务r1和r2,实际上相当于在t中开启了两个子线程,而两个子线程由线程池维护而已
pool.execute(r1);
pool.execute(r2);
};
};
//启动父线程
t.start();
}
}
//测试方法
public static void main(String[] args) {
//传入false代表要启动线程执行任务
test(false);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//执行任务5秒之后,传入false代表要停止线程
test(true);
} }

原来以为停止了父线程,子线程就会自动停止,事实证明这是错误的,必须在停止父线程的同时停止掉子线程才能彻底停止掉整个线程!

另:停止线程我使用了Thread类中的暴力停止方法stop,因为其他方法都不彻底,如有其他更好的方法,朋友们可以及时与我交流!

[置顶] 彻底停止运行线程池ThreadPoolExecutor的更多相关文章

  1. [置顶] 问题解决——XP线程池找不到QueueUserWorkItem

    2013年7月11号 主管让同事写一个并发100的小工具进行什么压力测试,据说是创建100个线程. 我表示这真真的是在坑人! 线程创建消耗资源,以自己的笔记本来跑这个东西,时间片都消耗在了线程切换上了 ...

  2. Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理

    相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...

  3. java面试总躲不过的并发(一): 线程池ThreadPoolExecutor基础梳理

    本文核心:线程池ThreadPoolExecutor基础梳理 一.实现多线程的方式 1.继承Thread类,重写其run方法 2.实现Runnable接口,实现run方法 3.实现Callable接口 ...

  4. JUC源码学习笔记5——1.5w字和你一起刨析线程池ThreadPoolExecutor源码,全网最细doge

    源码基于JDK8 文章1.5w字,非常硬核 系列文章目录和关于我 一丶从多鱼外卖开始 话说,王多鱼给好友胖子钱让其投资,希望亏得血本无归.胖子开了一个外卖店卖国宴,主打高端,外卖小哥都是自己雇佣,并且 ...

  5. java线程API学习 线程池ThreadPoolExecutor(转)

    线程池ThreadPoolExecutor继承自ExecutorService.是jdk1.5加入的新特性,将提交执行的任务在内部线程池中的可用线程中执行. 构造函数 ThreadPoolExecut ...

  6. Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理

    相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...

  7. 多线程学习笔记八之线程池ThreadPoolExecutor实现分析

    目录 简介 继承结构 实现分析 ThreadPoolExecutor类属性 线程池状态 构造方法 execute(Runnable command) addWorker(Runnable firstT ...

  8. java线程池ThreadPoolExecutor的使用

    package s.b.foo.caze.thread; import java.io.Serializable; import java.util.concurrent.ArrayBlockingQ ...

  9. 线程池ThreadPoolExecutor的学习

    我们知道,ExecutorService是一个抽象出线程池的一个接口,然后我们在使用线程池的时候,用的是Executors工具类中的一系列newCachedThreadPool() 等类似的方法,这些 ...

  10. Java 线程池 ThreadPoolExecutor 的那些事儿

    线程池基础知识 ThreadPoolExecutor : 一个线程池 Executors : 线程池工厂,通过该类可以取得一个拥有特定功能的线程池 ThreadPoolExecutor类实现了Exec ...

随机推荐

  1. 4、Web前端学习规划:JavaScript - 学习规划系列文章

    JavaScript作为Web前端里的第3重要的语言,笔者认为该重点进行学习.因为JavaScript衍生出来的框架和类库有不少,而且很强大.所以JavaScript的学习要抓好重点,在基本的语法及应 ...

  2. 如何快速提高英飞凌单片机编译器 TASKING TriCore Eclipse IDE 编译速度

    1.前言 使用英飞凌单片机编译器 TASKING TriCore Eclipse IDE 开发编译时,想必感受最深刻的就是编译速度,那是非常慢了,如果是部分修改的源文件编译还好,不用等太久,而如果选择 ...

  3. 小知识:安装系统后唯独搜不到自己的Wi-Fi

    遇到的问题,笔记本在安装Win10系统后在可用Wi-Fi热点中唯独搜不到自己的Wi-Fi. 咨询宽带售后的技术人员,说可能是因为我目前使用的是Wi-Fi 6,而我的笔记本可能是网卡过旧,不支持Wi-F ...

  4. Exadata存储节点的CPU限制成功了没?

    上篇随笔谈到刷1/8 rack时,日志显示存储节点已经成功限制CPU的,可如果使用mpstat命令看貌似还是64 CPU,难道实际没有成功吗? [root@dbm08celadm03 ~]# mpst ...

  5. 我自创的 Response泛型 返回类,全自动 推断,非常方便使用。

    package com.diandaxia.common.utils; import java.util.Date; /** * by liyuxin 2019.12.16 更新 * 统一返回格式 * ...

  6. 《ASP.NET Core 微服务实战》-- 读书笔记(第6章)

    第 6 章 事件溯源与 CQRS 在本章,我们来了解一下随着云平台一同出现的设计模式 我们先探讨事件溯源和命令查询职责分离(CQRS)背后的动机与哲学 事件溯源简介 事实由事件溯源而来 我们大脑就是一 ...

  7. Asp-Net-Core学习笔记:3.使用SignalR实时通信框架开发聊天室

    SignalR牛刀小试 在MVP杨老师的博客里看到这么个东西,我还以为是NetCore3才推出的新玩意,原来是已经有很多年的历史了,那看来还是比较成熟的一个技术了. 简介 SignalR是一个.NET ...

  8. 计网学习笔记十 Internet Routing Protocols

    上一讲简单介绍了routing和两种最小路径算法的使用,这节课讲了两种算法是如何糅合进协议中来实现具体使用的. 这一讲内容有AS的介绍,以及IGP和BGP协议. Autonomous Systems ...

  9. NC15172 情人节的电灯泡

    题目链接 题目 题目描述 情人节到了,小芳和小明手牵手,打算过一个完美的情人节,但是小刚偏偏也来了,当了一个明晃晃的电灯泡,小明很尴尬,就和小刚说,我交给你个任务,你完成了我俩就带你玩,否则你就回家吧 ...

  10. C++中两种获取UUID的方法(编程)

    第一种,依托WMI #define _WIN32_DCOM #include <iostream> using namespace std; #include <comdef.h&g ...