[Java] 线程池(收藏) →→→→→进入此内容的聊天室

来自 , 2019-10-21, 写在 Java, 查看 127 次.
URL http://www.code666.cn/view/9b698eb3
  1. import java.util.LinkedList;
  2.  
  3. /**
  4.  * 线程池,继承ThreadGroup。 ThreadGroup用于处理一组线程的类,它是一种树状结构,他的下层节点还可以是ThreadGroup对象
  5.  */
  6. public class MyThreadPool extends ThreadGroup {
  7.  
  8.         /** 标志线程池是否开启 */
  9.         private boolean isAlive;
  10.         /** 线程池中的任务队列 */
  11.         private LinkedList taskQueue;
  12.         /** 线程池中的线程ID */
  13.         private int threadID;
  14.         /** 线程池ID */
  15.         private static int threadPoolID;
  16.  
  17.         /**
  18.          * 创建新的线程池,numThreads是池中的线程数
  19.          */
  20.         public MyThreadPool(int numThreads) {
  21.                 super("ThreadPool-" + (threadPoolID++));
  22.                 // 设置为该线程池是的daemon属性为true,
  23.                 // 表示当该线程池中所有线程都被销毁时,该线程池会自动被销毁
  24.                 super.setDaemon(true);
  25.                 this.isAlive = true;
  26.                 // 新建一个任务队列
  27.                 this.taskQueue = new LinkedList();
  28.                 // 启动numThreads个工作线程
  29.                 for (int i = 0; i < numThreads; i++) {
  30.                         new PooledThread().start();
  31.                 }
  32.         }
  33.  
  34.         /**
  35.          * 添加新任务
  36.          */
  37.         public synchronized void performTask(Task task) {
  38.                 if (!this.isAlive) {
  39.                         // 线程被关则抛出IllegalStateException异常
  40.                         throw new IllegalStateException();
  41.                 }
  42.                 if (task != null) {
  43.                         // 将任务放到任务队列的尾部
  44.                         this.taskQueue.add(task);
  45.                         // 通知工作线程取任务
  46.                         notify();
  47.                 }
  48.  
  49.         }
  50.  
  51.         /**
  52.          * 获取任务
  53.          */
  54.         protected synchronized Task getTask() throws InterruptedException {
  55.                 // 如果任务列表为空,而且线程池没有被关闭,则继续等待任务
  56.                 while (this.taskQueue.size() == 0) {
  57.                         if (!this.isAlive) {
  58.                                 return null;
  59.                         }
  60.                         wait();
  61.                 }
  62.                 // 取任务列表的第一个任务
  63.                 return (Task) this.taskQueue.removeFirst();
  64.         }
  65.  
  66.         /**
  67.          * 关闭线程池,所有线程停止,不再执行任务
  68.          */
  69.         public synchronized void close() {
  70.                 if (isAlive) {
  71.                         this.isAlive = false;
  72.                         // 清除任务
  73.                         this.taskQueue.clear();
  74.                         // 中止线程池中所有线程
  75.                         this.interrupt();
  76.                 }
  77.         }
  78.  
  79.         /**
  80.          * 关闭线程池,并等待线程池中的所有任务被运行完。 但是不能接受新的任务。
  81.          */
  82.         public void join() {
  83.                 // 通知其他等待线程“该线程池已关闭”的消息
  84.                 synchronized (this) {
  85.                         isAlive = false;
  86.                         notifyAll();
  87.                 }
  88.                 // 等待所有线程完成
  89.                 // 首先建立一个新的线程数组。activeCount方法获取线程池中活动线程的估计数
  90.                 Thread[] threads = new Thread[this.activeCount()];
  91.                 // 将线程池中的活动线程拷贝到新创建的线程数组threads中。
  92.                 int count = this.enumerate(threads);
  93.                 for (int i = 0; i < count; i++) {
  94.                         try {
  95.                                 // 等待线程运行结束
  96.                                 threads[i].join();
  97.                         } catch (InterruptedException ex) {
  98.                         }
  99.                 }
  100.         }
  101.  
  102.         /**
  103.          * 内部类,用于执行任务的工作线程
  104.          */
  105.         private class PooledThread extends Thread {
  106.  
  107.                 // 构造方法
  108.                 public PooledThread() {
  109.                         // 第一个参数为该线程所在的线程组对象,即当前线程池对象
  110.                         // 第二个参数为线程名字
  111.                         super(MyThreadPool.this, "PooledThread-" + (threadID++));
  112.                 }
  113.  
  114.                 public void run() {
  115.                         // 如果该线程没有被中止
  116.                         while (!isInterrupted()) {
  117.  
  118.                                 // 获取任务
  119.                                 Task task = null;
  120.                                 try {
  121.                                         task = getTask();
  122.                                 } catch (InterruptedException ex) {
  123.                                 }
  124.  
  125.                                 // 只要线程池的任务列表不为空,getTask方法总能得到一个任务。
  126.                                 // 若getTask()返回null,则表示线程池中已经没有任务,而且线程池已被关闭。
  127.                                 if (task == null) {
  128.                                         return;
  129.                                 }
  130.  
  131.                                 // 运行任务,吸收异常
  132.                                 try {
  133.                                         task.perform();
  134.                                 } catch (Throwable t) {
  135.                                         // 当线程组中的线程有未被捕获的异常发生时,JVM就会去调用uncaughtException方法。
  136.                                         uncaughtException(this, t);
  137.                                 }
  138.                         }
  139.                 }
  140.         }
  141. }

回复 "线程池(收藏)"

这儿你可以回复上面这条便签

captcha