彻底停止运行线程池ThreadPoolExecutor

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

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

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

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

[java]  view plain  copy
  1. package com.iamzken.test;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5. import java.util.concurrent.ArrayBlockingQueue;  
  6. import java.util.concurrent.ThreadPoolExecutor;  
  7. import java.util.concurrent.TimeUnit;  
  8.   
  9. public class ThreadPoolExecutorTest {  
  10.     //线程池  
  11.     private static ThreadPoolExecutor pool = new ThreadPoolExecutor(355,  
  12.             TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10),  
  13.             new ThreadPoolExecutor.CallerRunsPolicy());  
  14.     //定义一个线程,相当于父线程  
  15.     private static Thread t;  
  16.     //保存线程池中当前所有正在执行任务的活动线程,相当于子线程  
  17.     private static List<Thread> activeThreads = new ArrayList<Thread>(5);  
  18.     //根据参数b的值,决定是启动线程还是停止线程  
  19.     public static void test(boolean b) {  
  20.   
  21.         if (b) {  
  22.             System.out.println("start========================================");  
  23.             //停止父线程,这里使用了Thread类的暴力停止方法stop  
  24.             t.stop();  
  25.             //遍历并停止所有子线程,这里使用了Thread类的暴力停止方法stop  
  26.             //这里一定要把子线程也停止掉,原来以为停止了父线程,子线程就会自动停止,事实证明这是错误的,必须在停止父线程的同时停止掉子线程才能彻底停止掉整个线程  
  27.             for (int i = 0; i < activeThreads.size(); i++) {  
  28.                 Thread t = activeThreads.get(i);  
  29.                 System.out.println(t.getName());  
  30.                 t.stop();  
  31.             }  
  32.               
  33.             System.out.println("stop==========================================");  
  34.         } else {  
  35.             //创建父线程  
  36.             t = new Thread() {  
  37.                 @Override  
  38.                 public void run() {  
  39.                     //创建线程池要执行的两个任务r1和r2。这两个任务都是死循环  
  40.                     Runnable r1 = new Thread() {  
  41.                         @Override  
  42.                         public void run() {  
  43.                             Thread currentThread = Thread.currentThread();  
  44.                             activeThreads.add(currentThread);  
  45.                             int i = 1;  
  46.                             while (true) {  
  47.                                 System.out.println(currentThread.getName()+"------------>"+(i++));  
  48.                                 try {  
  49.                                     Thread.sleep(1000);  
  50.                                 } catch (InterruptedException e) {  
  51.                                     e.printStackTrace();  
  52.                                 }  
  53.                             }  
  54.                         }  
  55.                     };  
  56.                     Runnable r2 = new Thread() {  
  57.                         @Override  
  58.                         public void run() {  
  59.                             Thread currentThread = Thread.currentThread();  
  60.                             activeThreads.add(currentThread);  
  61.                             int i = 1;  
  62.                             while (true) {  
  63.                                 System.out.println(currentThread.getName()+"------------>"+(i++));  
  64.                                 try {  
  65.                                     Thread.sleep(1000);  
  66.                                 } catch (InterruptedException e) {  
  67.                                     e.printStackTrace();  
  68.                                 }  
  69.                             }  
  70.                         }  
  71.                     };  
  72.                     //在线程池中执行两个任务r1和r2,实际上相当于在t中开启了两个子线程,而两个子线程由线程池维护而已  
  73.                     pool.execute(r1);  
  74.                     pool.execute(r2);  
  75.                 };  
  76.             };  
  77.             //启动父线程  
  78.             t.start();  
  79.         }  
  80.     }  
  81.     //测试方法  
  82.     public static void main(String[] args) {  
  83.         //传入false代表要启动线程执行任务  
  84.         test(false);  
  85.         try {  
  86.             Thread.sleep(5000);  
  87.         } catch (InterruptedException e) {  
  88.             e.printStackTrace();  
  89.         }  
  90.         //执行任务5秒之后,传入false代表要停止线程  
  91.         test(true);  
  92.     }  
  93.   
  94. }  


原来以为停止了父线程,子线程就会自动停止,事实证明这是错误的,必须在停止父线程的同时停止掉子线程才能彻底停止掉整个线程!
另:停止线程我使用了Thread类中的暴力停止方法stop,因为其他方法都不彻底,如有其他更好的方法,朋友们可以及时与我交流!

猜你喜欢

转载自blog.csdn.net/sayesan/article/details/80485069
今日推荐