java线程池(ThreadPoolExecutor)源码解析一

java线程池原理简要说明
java线程池(ThreadPoolExecutor)源码解析一
excecute()
reject(command)
java线程池(ThreadPoolExecutor)源码解析二
addWorker()
为什么workers使用HashSet和ReentraintLock而不使用并发的set
java线程池(ThreadPoolExecutor)源码解析三
ctl成员变量
java线程池(ThreadPoolExecutor)源码解析四
getTask()


线程池使用如下

 public static void main(String[] args) {
      int coreSize = 1;//核心线程数
      int maxSize = 2;//最大线程数
      long keepAliveTime = 10;//临时线程空闲时间
      TimeUnit unit = TimeUnit.MINUTES;//临时线程空闲时间单位
      BlockingQueue<Runnable> blockQueue = new LinkedBlockingQueue<Runnable>();//用于存任务的阻塞队列
      RejectedExecutionHandler handler = new RejectedExecutionHandler() {//任务队列满了以后对不能入队的任务的处理策略
          @Override
          public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
              System.out.println("线程池已满");
          }
      };
      ThreadPoolExecutor executor = new ThreadPoolExecutor(coreSize, maxSize, keepAliveTime, unit, blockQueue,
              handler);
      for (int i = 0; i < 10; i++) {
          executor.execute(new Runnable() {
              public void run() {
                  System.out.println(Thread.currentThread());
              }
          });
      }
      executor.shutdown();
  }

excecute()方法

可以看出核心方法是execute() 方法,下面是加了注释的execute()方法

public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        /*
         * 
         * 1. 如果线程数小于核心线程数,则启动一个新的线程,并将传入的runable作为他的第一个任务。
         * addWorker()方法自动检查线程池运行状态和工作线程数,如果当前状态不应该再启动新的线程,
         * addwoker()返回false
         * 
         * 2.  如果一个task成功进入队列,还是要再检查一次是否需要创建一个新的线程(因为在上一次检查后,
         * 之前存活的线程的生命周期可能已经结束了),或者进入这个方法之后线程池被关闭了。因此重新检查状态,
         * 根据情况来决定是移除任务还是再创建一个线程
         *
         * 3. 如果不能将任务放入队列,就尝试再启动一个新的线程。如果失败了,那就说明线程池关闭了或者线程池满了,
         * 所以后面执行拒绝策略
         */
        int c = ctl.get(); //ctl 是一个 AtomicInteger,用来存线程池的状态和工作线程数量,以后会说明
        if (workerCountOf(c) < corePoolSize) { //workerCountOf(c) 方法获取线程池已有线程数量
            if (addWorker(command, true)) //addWoker方法尝试创建新的线程执行任务
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) {
            int recheck = ctl.get();
            /*下面又进行了一次检查,主要是防止这种情况:线程A执行完上面的isRunning,返回运行中,然后挂起。
            * 这时候线程B调用了shutdown,关闭了线程池,这时候如果成功将线程池内所有线程结束了,这是线程A继续执行
            * workQueue.offer(command) 将任务入队,如果没有下面的第二次检查,这个任务将漏掉,既没有执行run方法,
            * 也没有执行拒绝策略
            */
            if (! isRunning(recheck) && remove(command))//isRunning(recheck) 返回当前线程的状态是否是运行中
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command); //reject方法很简单就是调用了传入的 rejectExcetpionHandler
    }

reject(command)方法

    /**
     * Invokes the rejected execution handler for the given command.
     * Package-protected for use by ScheduledThreadPoolExecutor.
     */
    final void reject(Runnable command) {
        handler.rejectedExecution(command, this);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值