| New file | 
 |  |  | 
 |  |  | package com.dy.common.threadPool; | 
 |  |  |  | 
 |  |  | import java.util.*; | 
 |  |  |  | 
 |  |  | import org.apache.logging.log4j.*; | 
 |  |  |  | 
 |  |  | import com.dy.common.threadPool.ThreadPool.Job; | 
 |  |  |  | 
 |  |  | public class ThreadPoolImp { | 
 |  |  | 	 | 
 |  |  |    /** | 
 |  |  |     * 线程池实现 | 
 |  |  |     * @author Administrator | 
 |  |  |     * | 
 |  |  |     */ | 
 |  |  |    public class MyThreadPool implements ThreadPool.Pool{ | 
 |  |  | 		 | 
 |  |  |       /** | 
 |  |  |        * 线程池唯一实例 | 
 |  |  |        */ | 
 |  |  |       public MyThreadPool myPool ; | 
 |  |  |  | 
 |  |  |       /** | 
 |  |  |        * 线程池名称; | 
 |  |  |        */ | 
 |  |  |       private String poolName ; | 
 |  |  |       /** | 
 |  |  |        * 空闲线程集合 | 
 |  |  |        */ | 
 |  |  |       private List<MyThread> freeThreads; | 
 |  |  |  | 
 |  |  |       /** | 
 |  |  |        * 工作中的线程集合 | 
 |  |  |        */ | 
 |  |  |       private List<MyThread> busiThreads; | 
 |  |  |  | 
 |  |  |       /** | 
 |  |  |        * 线程池最大线程数 , 若maxNum <= 0,则maxNum = 1 。 | 
 |  |  |        */ | 
 |  |  |       private int maxNum; | 
 |  |  |  | 
 |  |  |       /** | 
 |  |  |        * 最小线程数,若minNum > maxNum,则minNum = maxNum 。 | 
 |  |  |        */ | 
 |  |  |       private int minNum; | 
 |  |  |  | 
 |  |  |       /** | 
 |  |  |        * 当前线程池中的线程数。 | 
 |  |  |        */ | 
 |  |  |       private int currNum; | 
 |  |  | 		 | 
 |  |  |       /** | 
 |  |  |        * 空闲线程超时的时长(秒),超过这个时间,就清除多余线程, | 
 |  |  |        * 使空闲线程最多是minNum个 | 
 |  |  |        */ | 
 |  |  |       private long freeTimeout ; | 
 |  |  | 		 | 
 |  |  |       /** | 
 |  |  |        * 忙碌线程超时的时长(秒),超过这个时间,就认为是崩溃线程,将被清除。 | 
 |  |  |        */ | 
 |  |  |       private long busyTimeout ; | 
 |  |  |  | 
 |  |  |       /** | 
 |  |  |        * 同步对象 | 
 |  |  |        */ | 
 |  |  |       private Object synObj = new Object(); | 
 |  |  |  | 
 |  |  |       /** | 
 |  |  |        * 内部启动的空闲和忙碌超时线程的线程 | 
 |  |  |        */ | 
 |  |  |       private Thread monitorThread ; | 
 |  |  |  | 
 |  |  |       /** | 
 |  |  |        * 日志  | 
 |  |  |        */ | 
 |  |  |       private static final Logger log = LogManager.getLogger(MonitorThread.class) ; | 
 |  |  |  | 
 |  |  |       /** | 
 |  |  |        * 线程池构造方法 | 
 |  |  |        * @param poolName 线程池和线程名称 | 
 |  |  |        * @param maxNum 线程池最大线程数,若为-1,不受限制 | 
 |  |  |        * @param minNum 线程池最小线程数,或初始线程数 | 
 |  |  |        * @param freeTimeout 空闲线程超时时长(秒) | 
 |  |  |        * @param busyTimeout 忙碌线程超时时长(秒),若为-1,不受限制 | 
 |  |  |        */ | 
 |  |  |       public MyThreadPool( | 
 |  |  |             String poolName ,  | 
 |  |  |             Integer maxNum ,  | 
 |  |  |             Integer minNum , | 
 |  |  |             Long freeTimeout , | 
 |  |  |             Long busyTimeout) { | 
 |  |  |          if(poolName == null){ | 
 |  |  |             poolName="线程池" ; | 
 |  |  |          } | 
 |  |  |          this.poolName = poolName ; | 
 |  |  | 			 | 
 |  |  |          if(maxNum == null || maxNum.intValue() < 0){ | 
 |  |  |             maxNum = 65535 ; | 
 |  |  |          } | 
 |  |  |          if(minNum == null || minNum.intValue() < 0){ | 
 |  |  |             minNum = 0 ; | 
 |  |  |          } | 
 |  |  |          if(minNum > maxNum){ | 
 |  |  |             minNum = maxNum ; | 
 |  |  |          } | 
 |  |  |          this.maxNum = maxNum ; | 
 |  |  |          this.minNum = minNum ; | 
 |  |  |          this.currNum = 0; | 
 |  |  | 			 | 
 |  |  |          if(freeTimeout == null || freeTimeout.longValue() <= 0){ | 
 |  |  |             freeTimeout = 60000L ; | 
 |  |  |          } | 
 |  |  |          this.freeTimeout = freeTimeout ; | 
 |  |  | 			 | 
 |  |  |          if(busyTimeout == null || busyTimeout.longValue() <= 0){ | 
 |  |  |             this.busyTimeout = -1L ; | 
 |  |  |          }else{ | 
 |  |  |             this.busyTimeout = busyTimeout ;	 | 
 |  |  |          } | 
 |  |  |          if(maxNum != 0){ | 
 |  |  |             this.busiThreads = new ArrayList<>(); | 
 |  |  |             this.freeThreads = new ArrayList<>(); | 
 |  |  |             //最小化线程池 | 
 |  |  |             for (int i = 0; i < this.minNum ; i++) { | 
 |  |  |                MyThread t = new MyThread(this); | 
 |  |  |                t.start(); | 
 |  |  |                this.freeThreads.add(t); | 
 |  |  |                this.currNum++; | 
 |  |  |             } | 
 |  |  |             this.monitorThread = new MonitorThread(this) ; | 
 |  |  |             this.monitorThread.start() ; | 
 |  |  |          } | 
 |  |  |       } | 
 |  |  |       /** | 
 |  |  |        * 线程池中线程个数 | 
 |  |  |        * @return | 
 |  |  |        */ | 
 |  |  |       @Override | 
 |  |  |       public Integer size() { | 
 |  |  |          return currNum ; | 
 |  |  |       } | 
 |  |  |       @Override | 
 |  |  |       public Integer maxThread() { | 
 |  |  |          return maxNum ; | 
 |  |  |       } | 
 |  |  |       @Override | 
 |  |  |       public Integer minThread() { | 
 |  |  |          return minNum ; | 
 |  |  |       } | 
 |  |  |  | 
 |  |  |       /** | 
 |  |  |        * 把所要执行的工作对象实例放入线程池中 | 
 |  |  |        * @param job ThreadJob 工作对象实例 | 
 |  |  |        * @throws Exception  | 
 |  |  |        */ | 
 |  |  |       @Override | 
 |  |  |       public void putJob(Job job) throws Exception { | 
 |  |  |          if(this.busiThreads == null || this.freeThreads == null){ | 
 |  |  |             throw new Exception("线程池未启动") ; | 
 |  |  |          } | 
 |  |  |          synchronized(this.synObj) { | 
 |  |  |             //log.debug("工作任务分配到线程池中。") ; | 
 |  |  |             MyThread t = null ; | 
 |  |  |             if (this.freeThreads.size() == 0) { | 
 |  |  |                //当前没有空闲线程 | 
 |  |  |                if (this.maxNum == -1 || this.currNum < this.maxNum) { | 
 |  |  |                   //当前线程数未达到最大值 , 增加新的线程 | 
 |  |  |                   t = new MyThread(this); | 
 |  |  |                   t.start(); | 
 |  |  |                   this.currNum++; | 
 |  |  |                } else { | 
 |  |  |                   //当前线程达到最大数了,等待回归线程 | 
 |  |  |                   while (freeThreads.size() == 0) { | 
 |  |  |                      //如果没有空闲的线程,等待工作线程工作完成回来 | 
 |  |  |                      try { | 
 |  |  |                         //log.warn("线程池(" + this.poolName + ")中线程数达到上限,新工作任务等待释放线程!");  | 
 |  |  |                         synObj.wait(); | 
 |  |  |                      } catch (Exception e) { | 
 |  |  |                         log.error("'" + this.poolName + "'线程池中线程等待释放线时发生等待异常!", e); | 
 |  |  |                      } | 
 |  |  |                      t = (MyThread) freeThreads.get(0); | 
 |  |  |                      if (t != null) { | 
 |  |  |                         //说明得到了释放回来的线程 | 
 |  |  |                         freeThreads.remove(0); | 
 |  |  |                         break; | 
 |  |  |                      }else{ | 
 |  |  |                         //说明没有得到释放回来的线程,可以其他线程 | 
 |  |  |                         continue; | 
 |  |  |                      } | 
 |  |  |                   }//end while | 
 |  |  |                }//end else | 
 |  |  |             }//end if(freeThreads.size() == 0) | 
 |  |  |             else { | 
 |  |  |                t = (MyThread) freeThreads.get(0); | 
 |  |  |                freeThreads.remove(0); | 
 |  |  |             } | 
 |  |  |             busiThreads.add(t); | 
 |  |  |             t.putJob(job); | 
 |  |  |          } | 
 |  |  |       } | 
 |  |  |  | 
 |  |  |       /** | 
 |  |  |        * 线程工作完成,从busiThreads回归freeThreads | 
 |  |  |        */ | 
 |  |  |       protected void freeThread(MyThread t) throws Exception { | 
 |  |  |          if(this.busiThreads == null || this.freeThreads == null){ | 
 |  |  |             throw new Exception("线程池未启动") ; | 
 |  |  |          } | 
 |  |  |          synchronized (synObj) { | 
 |  |  |             busiThreads.remove(t); | 
 |  |  |             freeThreads.add(t); | 
 |  |  |             synObj.notify(); | 
 |  |  |          } | 
 |  |  |       } | 
 |  |  | 		 | 
 |  |  |       /** | 
 |  |  |        * 监控超时线程的线程 | 
 |  |  |        * @author Administrator | 
 |  |  |        * | 
 |  |  |        */ | 
 |  |  |       protected class MonitorThread extends Thread { | 
 |  |  |          private MyThreadPool pool ; | 
 |  |  | 			 | 
 |  |  |          private MyThread t  ; | 
 |  |  |          private Iterator<?> it  ; | 
 |  |  |  | 
 |  |  |          /** | 
 |  |  |           *  | 
 |  |  |           * @param pool 池 | 
 |  |  |           */ | 
 |  |  |          public MonitorThread(MyThreadPool pool){ | 
 |  |  |             this.pool = pool ; | 
 |  |  |          } | 
 |  |  |          /** | 
 |  |  |           *  | 
 |  |  |           */ | 
 |  |  |          @SuppressWarnings("finally") | 
 |  |  |          public void run(){ | 
 |  |  |             long interval = pool.freeTimeout ; | 
 |  |  |             if(pool.busyTimeout > 0 && pool.busyTimeout < pool.freeTimeout){ | 
 |  |  |                interval = pool.busyTimeout ; | 
 |  |  |             } | 
 |  |  |             boolean isException = false ; | 
 |  |  |             while(true){ | 
 |  |  |                t = null ; | 
 |  |  |                it = null ; | 
 |  |  |                try{ | 
 |  |  |                   MonitorThread.sleep(interval) ; | 
 |  |  |                }catch(Exception e){ | 
 |  |  |                   isException = true ; | 
 |  |  |                }finally{ | 
 |  |  |                   if(isException){ | 
 |  |  |                      isException = false ; | 
 |  |  |                      continue ; | 
 |  |  |                   } | 
 |  |  |                } | 
 |  |  |                try{ | 
 |  |  |                   synchronized (pool.synObj) { | 
 |  |  |                      if(pool.freeThreads.size() > pool.minNum){ | 
 |  |  |                         //如果空闲线程大于最小线程数,则清理空闲线程 | 
 |  |  |                         int num = pool.freeThreads.size() - pool.minNum ; | 
 |  |  |                         int count = 0 ; | 
 |  |  |                         it = pool.freeThreads.iterator() ; | 
 |  |  |                         while(it.hasNext()){ | 
 |  |  |                            if(count == num) { | 
 |  |  |                               break ; | 
 |  |  |                            } | 
 |  |  |                            count ++ ; | 
 |  |  |                            t = (MyThread)it.next() ; | 
 |  |  |                            if((System.currentTimeMillis() - t.time) >= pool.freeTimeout){ | 
 |  |  |                               it.remove() ; | 
 |  |  |                               pool.currNum-- ; | 
 |  |  |                               //log.debug("线程池(" + pool.poolName + ")中清除了一个超时空闲线程!");  | 
 |  |  |                               t.destroy() ; | 
 |  |  |                               t = null ; | 
 |  |  |                            } | 
 |  |  |                         } | 
 |  |  |                      }//end if | 
 |  |  | 							 | 
 |  |  |                      if(pool.busyTimeout != -1 && pool.busyTimeout > 0){ | 
 |  |  |                         it = pool.busiThreads.iterator() ; | 
 |  |  |                         while(it.hasNext()){ | 
 |  |  |                            t = (MyThread)it.next() ; | 
 |  |  |                            if((System.currentTimeMillis() - t.time) >= pool.busyTimeout){ | 
 |  |  |                               it.remove() ; | 
 |  |  |                               pool.currNum-- ; | 
 |  |  |                               log.error("线程池(" + pool.poolName + ")中清除了一个超时崩溃(忙碌)线程!");  | 
 |  |  |                               t.destroy() ; | 
 |  |  |                               t = null ; | 
 |  |  |                            } | 
 |  |  |                         } | 
 |  |  |                      } | 
 |  |  |                   }//end synchronized (pool.synObj) | 
 |  |  |                }catch(Exception e){ | 
 |  |  |                   e.printStackTrace(); | 
 |  |  |                }finally{ | 
 |  |  |                   continue ; | 
 |  |  |                } | 
 |  |  |             }//end while(true) | 
 |  |  |          } | 
 |  |  |       } | 
 |  |  | 		 | 
 |  |  | 		 | 
 |  |  |    } | 
 |  |  |  | 
 |  |  |    /** | 
 |  |  |     * 池中线程实现 | 
 |  |  |     * @author Administrator | 
 |  |  |     * | 
 |  |  |     */ | 
 |  |  |    public class MyThread extends Thread{ | 
 |  |  |  | 
 |  |  |       /** | 
 |  |  |        * 标示线程是活的 | 
 |  |  |        */ | 
 |  |  |       private boolean living = true ; | 
 |  |  | 		 | 
 |  |  |       /** | 
 |  |  |        * 线程忙碌或空闲记时器 | 
 |  |  |        */ | 
 |  |  |       protected long time ; | 
 |  |  | 		 | 
 |  |  |       /** | 
 |  |  |        * 当前线程所处的线程池 | 
 |  |  |        */ | 
 |  |  |       private MyThreadPool pool ; | 
 |  |  |       /** | 
 |  |  |        * 线程具体工作的回调类 | 
 |  |  |        */ | 
 |  |  |       private Job job ; | 
 |  |  | 		 | 
 |  |  |       /** | 
 |  |  |        * 指示线程可以工作 | 
 |  |  |        */ | 
 |  |  |       private Boolean canJob ; | 
 |  |  | 		 | 
 |  |  |       private Logger log = LogManager.getLogger(MyThread.class.getName()) ; | 
 |  |  |  | 
 |  |  |       protected MyThread(MyThreadPool pool) { | 
 |  |  |          super(); | 
 |  |  |          this.pool = pool ; | 
 |  |  |          this.time = 0 ; | 
 |  |  |          this.canJob = false ; | 
 |  |  |       } | 
 |  |  | 		 | 
 |  |  |       /** | 
 |  |  |        * 设置线程工作对象 | 
 |  |  |        * @param job 工作 | 
 |  |  |        */ | 
 |  |  |       protected void putJob(Job job) throws Exception { | 
 |  |  |          if(job == null){ | 
 |  |  |             this.job = new Job(){ | 
 |  |  |                public void execute(){ | 
 |  |  |                } | 
 |  |  |                public void destroy(){ | 
 |  |  |                } | 
 |  |  |                public boolean isDestroy(){ | 
 |  |  |                   return false ; | 
 |  |  |                } | 
 |  |  |             }; | 
 |  |  |          } | 
 |  |  |          synchronized (this) { | 
 |  |  |             this.job = job ; | 
 |  |  |             this.canJob = true; | 
 |  |  |             //忙碌记时开始 | 
 |  |  |             this.time = System.currentTimeMillis() ; | 
 |  |  |             this.notify(); | 
 |  |  |          } | 
 |  |  |       } | 
 |  |  |  | 
 |  |  |       /** | 
 |  |  |        *  | 
 |  |  |        */ | 
 |  |  |       @SuppressWarnings("finally") | 
 |  |  |       @Override | 
 |  |  |       public void run(){ | 
 |  |  |          while (living){ | 
 |  |  |             synchronized (this){ | 
 |  |  |                while(!canJob){ | 
 |  |  |                   //当不能工作时 | 
 |  |  |                   try{ | 
 |  |  |                      this.wait(); | 
 |  |  |                   }catch (Exception e) { | 
 |  |  |                      log.error("线程池(" + pool.poolName + ")的工作线程等待可以工作的信号时发生等待异常:\n" + e.getMessage(),  e); | 
 |  |  |                      this.canJob = false ; | 
 |  |  |                      continue; | 
 |  |  |                   } | 
 |  |  |                } | 
 |  |  |                /////////////////////// | 
 |  |  |                //被唤醒,有新工作了 | 
 |  |  |                try{ | 
 |  |  |                   if(this.job != null){ | 
 |  |  |                      this.job.execute() ; | 
 |  |  |                   } | 
 |  |  |                }catch (Exception ee) { | 
 |  |  |                   log.error("线程池(" + pool.poolName + ")的工作线程在执行工作时发生异常:\n" + ee.getMessage(), ee); | 
 |  |  |                   //ee.printStackTrace() ; | 
 |  |  |                }finally { | 
 |  |  |                   this.canJob = false ; | 
 |  |  |                   this.job = null ; | 
 |  |  |                   if(living){ | 
 |  |  |                      //线程未被销毁 | 
 |  |  |                      this.free() ; | 
 |  |  |                   } | 
 |  |  |                   continue; | 
 |  |  |                } | 
 |  |  |             }// end synchronized(this) | 
 |  |  |          }// end while(living) | 
 |  |  |       } | 
 |  |  | 		 | 
 |  |  |       public void free(){ | 
 |  |  |          try{ | 
 |  |  |             //使本线程回归空闲线程池 | 
 |  |  |             pool.freeThread(this); | 
 |  |  |             //空闲开始记时 | 
 |  |  |             this.time = System.currentTimeMillis() ; | 
 |  |  |             // 没有可做的了 | 
 |  |  |             this.canJob = false; | 
 |  |  |             log.debug("线程池(" + this.pool.poolName + ")中的线程回归空闲集合。"); | 
 |  |  |          }catch (Exception e){ | 
 |  |  |             log.error("线程池(" + pool.poolName + ")的工作线程释放回归时发生异常:\n" + e.getMessage(), e); | 
 |  |  |             e.printStackTrace(); | 
 |  |  |          } | 
 |  |  |  | 
 |  |  |       } | 
 |  |  |  | 
 |  |  |       /** | 
 |  |  |        * 销毁工作线程 | 
 |  |  |        */ | 
 |  |  |       public void destroy() { | 
 |  |  |          //线程销毁前,首先把其所持有的工作销毁,否则线程停不下来,也销毁不了 | 
 |  |  |          if(this.job != null){ | 
 |  |  |             this.job.destroy(); | 
 |  |  |          } | 
 |  |  |          this.living = false ;//使线程从run方法的长久while(living)中退出来,从线程自动销毁 | 
 |  |  |          this.job = null ;  | 
 |  |  |       } | 
 |  |  |    } | 
 |  |  | } |