自己动手写线程池——向JDK线程池进发( 二 )


  • 有自己的拒绝策略,当任务队列满了,线程数也达到最大的时候,需要拒绝提交的任务 。
  • 线程池参数介绍【自己动手写线程池——向JDK线程池进发】  private AtomicInteger ct = new AtomicInteger(0); // 当前在执行任务的线程个数  private int corePoolSize;  private int maximumPoolSize;  private long keepAliveTime;  private TimeUnit unit;  private BlockingQueue<Runnable> taskQueue;  private RejectPolicy policy;  private ArrayList<Worker> workers = new ArrayList<>();  private volatile boolean isStopped;  private boolean useTimed;参数解释如下:
    • ct:表示当前线程池当中线程的个数 。
    • corePoolSize:线程池当中核心线程的个数,意义和上面谈到的JDK的线程池意义一致 。
    • maximumPoolSize:线程池当中最大的线程个数,意义和上面谈到的JDK的线程池意义一致 。
    • keepAliveTime 和 unit:和JDK线程池的参数意义一致 。
    • taskQueue:任务队列,用不保存提交的任务 。
    • policy:拒绝策略,主要有一下四种策略:
    public enum RejectPolicy {  ABORT,  CALLER_RUN,  DISCARD_OLDEST,  DISCARD}
    • workers:用于保存工作线程 。
    • isStopped:线程池是否被关闭了 。
    • useTimed:主要是用于表示是否使用上面的 keepAliveTime 和 unit,如果使用就是在一定的时间内,如果没有从任务队列当中获取到任务,线程就从线程池退出,但是需要保证线程池当中最小的线程个数不小于 corePoolSize。
    实现Runnable  // 下面这个方法是向线程池提交任务  public void execute(Runnable runnable) throws InterruptedException {    checkPoolState();    if (addWorker(runnable, false)  // 如果能够加入新的线程执行任务 加入成功就直接返回            || !taskQueue.offer(runnable) // 如果 taskQueue.offer(runnable) 返回 false 说明提交任务失败 任务队列已经满了            || addWorker(runnable, true)) // 使用能够使用的最大的线程数 (maximumPoolSize) 看是否能够产生新的线程      return;    // 如果任务队列满了而且不能够加入新的线程 则拒绝这个任务    if (!taskQueue.offer(runnable))      reject(runnable);  }在上面的代码当中:
    • checkPoolState函数是检查线程池的状态,当线程池被停下来之后就不能够在提交任务:
      private void checkPoolState() {    if (isStopped) {      // 如果线程池已经停下来了,就不在向任务队列当中提交任务了      throw new RuntimeException("thread pool has been stopped, so quit submitting task");    }  }