[置顶] 彻底停止运行线程池ThreadPoolExecutor
最近系统开发时遇到这样一个需求:
该功能执行时间很久,如果运行过程出现错误,也无法将其停止,必须眼睁睁的看着它浪费很久时间,除非停止服务器。
于是,我就想着如何给该功能加上一个“停止”的功能呢?
经过不断的思考和测试,发现思路如此简单,直接上代码!
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,因为其他方法都不彻底,如有其他更好的方法,朋友们可以及时与我交流!