线程池(一)-源码分析

本文详细解析了JavaThreadPoolExecutor的工作原理,包括任务的添加、线程的创建与停止机制,以及如何控制线程数量、状态管理和任务拒绝策略。
摘要由CSDN通过智能技术生成

线程池

源码分析

新增任务
  1. 当状态>=SHUTDOWN时,不允许新增任务
public class ThreadPoolExecutor extends AbstractExecutorService {
    public void execute(Runnable command) {
        if (command == null)
            throw new NullPointerException();
        int c = ctl.get();
        if (workerCountOf(c) < corePoolSize) {
            if (addWorker(command, true)) //1.新增线程(带初始任务)
                return;
            c = ctl.get();
        }
        if (isRunning(c) && workQueue.offer(command)) { //2.添加到任务队列
            int recheck = ctl.get();
            if (! isRunning(recheck) && remove(command))
                reject(command);
            else if (workerCountOf(recheck) == 0)
                addWorker(null, false);
        }
        else if (!addWorker(command, false))
            reject(command);
    }
    
    //新增执行任务的线程
    private boolean addWorker(Runnable firstTask, boolean core) { 
        retry:
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);
            if (rs >= SHUTDOWN &&  //状态>=SHUTDOWN时,不允许新增任务
                ! (rs == SHUTDOWN &&
                   firstTask == null &&
                   ! workQueue.isEmpty()))
                return false;
            for (;;) {
                int wc = workerCountOf(c); 
                if (wc >= CAPACITY ||
                    wc >= (core ? corePoolSize : maximumPoolSize)) 
                    return false;
                if (compareAndIncrementWorkerCount(c)) //cas增加线程数量成功
                    break retry;
                c = ctl.get();  
                if (runStateOf(c) != rs)
                    continue retry;
            }
        }
        boolean workerStarted = false;
        boolean workerAdded = false;
        Worker w = null;
        try {
            w = new Worker(firstTask); //新增线程
            final Thread t = w.thread;
            if (t != null) {
                final ReentrantLock mainLock = this.mainLock;
                mainLock.lock();//全局独占锁访问workers资源
                try {
                    int rs = runStateOf(ctl.get());
                    if (rs < SHUTDOWN ||
                        (rs == SHUTDOWN && firstTask == null)) {//再次判断状态>=SHUTDOWN?
                                                                //如果状态>=SHUTDOWN,需要把上面增加新增的线程数-1
                                                                //如果状态<SHUTDOWN,则把线程添加到workers列表中
                        if (t.isAlive()) 
                            throw new IllegalThreadStateException();
                        workers.add(w); //添加线程到workers列表中
                        int s = workers.size();
                        if (s > largestPoolSize)
                            largestPoolSize = s;
                        workerAdded = true;
                    }
                } finally {
                    mainLock.unlock();//释放全局独占锁
                }
                if (workerAdded) {
                    t.start(); //启动线程
                    workerStarted = true;
                }
            }
        } finally {
            if (! workerStarted)
                addWorkerFailed(w); //这里是再次判断状态>=SHUTDOWN==true,需要减少线程数
        }
        return workerStarted;
    }
      
    //新增线程失败
    private void addWorkerFailed(Worker w) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();//全局独占锁访问workers资源
        try {
            if (w != null)
                workers.remove(w);//从workers列表删除线程
            decrementWorkerCount();//cas减少线程数量
            tryTerminate();
        } finally {
            mainLock.unlock();//释放全局独占锁
        }
    }
}
线程执行任务
  1. 当状态>=STOP时,不再从任务队列取任务处理 (状态SHUTDOWN && workQueue.isEmpty()和状态STOP可以视为一样的状态)
public class ThreadPoolExecutor extends AbstractExecutorService {
        private final class Worker extends AbstractQueuedSynchronizer implements Runnable{
            
        public void run() {
           runWorker(this);
        }
            
        final void runWorker(Worker w) {
           Thread wt = Thread.currentThread();
           Runnable task = w.firstTask;
           w.firstTask = null;
           w.unlock(); 
           boolean completedAbruptly = true;
           try {
               while (task != null || (task = getTask()) != null) { //获取任务
                   w.lock();//这里是判断当前线程是否空闲,有锁就是忙,没锁就是空闲 ,只有空闲的线程才会被中断
                   
                   if ((runStateAtLeast(ctl.get(), STOP) ||
                        (Thread.interrupted() &&
                         runStateAtLeast(ctl.get(), STOP))) && //状态>=STOP || 线程被中断 结束
                                                              
                       !wt.isInterrupted())
                       wt.interrupt();
                   try {
                       beforeExecute(wt, task);
                       Throwable thrown = null;
                       try {
                           task.run();//处理任务
                       } catch (RuntimeException x) {
                           thrown = x; throw x;
                       } catch (Error x) {
                           thrown = x; throw x;
                       } catch (Throwable x) {
                           thrown = x; throw new Error(x);
                       } finally {
                           afterExecute(task, thrown);
                       }
                   } finally {
                       task = null;
                       w.completedTasks++;
                       w.unlock();
                   }
               }
               completedAbruptly = false;
           } finally {
               processWorkerExit(w, completedAbruptly);//线程结束处理
           }
       }

       //获取任务
       private Runnable getTask() {
           boolean timedOut = false; 
           for (;;) {
               int c = ctl.get();
               int rs = runStateOf(c);
               if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) { 
                   decrementWorkerCount();
                   return null;
               }
               int wc = workerCountOf(c);
               boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
               if ((wc > maximumPoolSize || (timed && timedOut))
                   && (wc > 1 || workQueue.isEmpty())) {
                   if (compareAndDecrementWorkerCount(c))
                       return null;
                   continue;
               }
   
               try {
                   Runnable r = timed ?
                       workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                       workQueue.take();//设置挂起状态=SLEEP && 状态<STOP && 任务队列为空 挂起
                   if (r != null)
                       return r;
                   timedOut = true;
               } catch (InterruptedException retry) {
                   timedOut = false;
               }
           }
       }
}
线程停止
public class ThreadPoolExecutor extends AbstractExecutorService {
      //尝试关闭线程池
    final void tryTerminate() {
       for (;;) {
            int c = ctl.get();
            if (isRunning(c) ||
                runStateAtLeast(c, TIDYING) ||
                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))//判断状态==STOP才需要停止线程,其他情况不需要
                return;
            if (workerCountOf(c) != 0) {   //当前线程数!=0
                interruptIdleWorkers(ONLY_ONE); //停止一个空闲线程
                return;
            }
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock(); //全局独占锁来处理全局资源
            try {
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) { //当前线程数==0,设置线程池状态为TIDYING
                    try {
                        terminated(); 
                    } finally {
                        ctl.set(ctlOf(TERMINATED, 0));//前线程数==0,设置线程池状态为TERMINATED
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                mainLock.unlock();//释放全局独占锁
            }
        }
    }
    
    //停止空闲线程
    private void interruptIdleWorkers(boolean onlyOne) {
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();//全局独占锁访问workers
        try {
           for (Worker w : workers) {
               Thread t = w.thread;
               if (!t.isInterrupted() && w.tryLock()) {//尝试加锁,加锁失败说明要中断的线程正在执行任务而不是在获取任务,这时不能被看成空闲线程
                   try {
                       t.interrupt(); //中断线程
                   } catch (SecurityException ignore) {
                   } finally {
                       w.unlock();//释放锁
                   }
               }
               if (onlyOne)
                  break;
          }
      } finally {
           mainLock.unlock();//释放全局独占锁
      }
   }
    
   //Worker类
   private final class Worker extends AbstractQueuedSynchronizer implements Runnable{
       //锁结构
       Worker(Runnable firstTask) {
            setState(-1); 
            this.firstTask = firstTask;
            this.thread = getThreadFactory().newThread(this);
        }
        protected boolean isHeldExclusively() {
            return getState() != 0;
        }

        protected boolean tryAcquire(int unused) {
            if (compareAndSetState(0, 1)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }

        protected boolean tryRelease(int unused) {
            setExclusiveOwnerThread(null);
            setState(0);
            return true;
        }

        public void lock()        { acquire(1); }
        public boolean tryLock()  { return tryAcquire(1); }
        public void unlock()      { release(1); }
        public boolean isLocked() { return isHeldExclusively(); }
    
    
        //执行任务的线程Worker
        final void runWorker(Worker w) {
            Thread wt = Thread.currentThread();
            Runnable task = w.firstTask;
            w.firstTask = null;
            w.unlock(); //初始化锁
            boolean completedAbruptly = true;
            try {
               while (task != null || (task = getTask()) != null) { 
                   w.lock(); //加锁
                   
                   if ((runStateAtLeast(ctl.get(), STOP) ||
                        (Thread.interrupted() &&
                         runStateAtLeast(ctl.get(), STOP))) && 
                       !wt.isInterrupted())
                       wt.interrupt();
                   try {
                       beforeExecute(wt, task);
                       Throwable thrown = null;
                       try {
                           task.run();
                       } catch (RuntimeException x) {
                           thrown = x; throw x;
                       } catch (Error x) {
                           thrown = x; throw x;
                       } catch (Throwable x) {
                           thrown = x; throw new Error(x);
                       } finally {
                           afterExecute(task, thrown);
                       }
                   } finally {
                       task = null;
                       w.completedTasks++;
                       w.unlock();//释放锁
                   }
               }
               completedAbruptly = false;
           } finally {
               processWorkerExit(w, completedAbruptly);
           }
       }
   }
}      
线程数量控制
  1. 线程数量<corePoolSize,新增线程
  2. 任务队列未满,添加到任务队列
  3. 任务队列已满,线程数量必须<maximumPoolSize,新增线程
  4. 线程数量>maximumPoolSize,执行拒绝策略
  5. 状态为STOP时,线程数量要降为0

控制线程的数量就是通过新增线程和线程停止来控制的

  1. 新增线程(addWorker(null, false))
  2. 线程停止(tryTerminate)
新增任务
public class ThreadPoolExecutor extends AbstractExecutorService {
       private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
       private static final int COUNT_BITS = Integer.SIZE - 3;
       private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

       private static final int RUNNING    = -1 << COUNT_BITS;
       private static final int SHUTDOWN   =  0 << COUNT_BITS;
       private static final int STOP       =  1 << COUNT_BITS;
       private static final int TIDYING    =  2 << COUNT_BITS;
       private static final int TERMINATED =  3 << COUNT_BITS;

       private static int runStateOf(int c)     { return c & ~CAPACITY; }
       private static int workerCountOf(int c)  { return c & CAPACITY; }
       private static int ctlOf(int rs, int wc) { return rs | wc; }
    
       private boolean compareAndIncrementWorkerCount(int expect) {
           return ctl.compareAndSet(expect, expect + 1);
       }
       private boolean compareAndDecrementWorkerCount(int expect) {
           return ctl.compareAndSet(expect, expect - 1);
       }
       
       //使用线程池执行任务
       public void execute(Runnable command) {
           if (command == null)
               throw new NullPointerException();
           int c = ctl.get();
           if (workerCountOf(c) < corePoolSize) { //线程数量< corePoolSize
               if (addWorker(command, true)) 
                   return;
               c = ctl.get();
           }
           if (isRunning(c) && workQueue.offer(command)) { //队列未满
               int recheck = ctl.get();
               if (! isRunning(recheck) && remove(command))
                   reject(command);
               else if (workerCountOf(recheck) == 0)//队列中有任务,但是没有可用的线程
                   addWorker(null, false); //创建一个不带初始任务的线程
           }
           else if (!addWorker(command, false))//队列已满,core==false表示可以让线程继续新增直到maximumPoolSize
               reject(command);//新增任务失败使用拒绝策略
        }
    
        //新增线程
        private boolean addWorker(Runnable firstTask, boolean core) { 
           retry:
           for (;;) {
               int c = ctl.get();
               int rs = runStateOf(c);
               if (rs >= SHUTDOWN &&  
                   ! (rs == SHUTDOWN &&
                      firstTask == null &&
                      ! workQueue.isEmpty()))
                   return false;
               for (;;) {
                   int wc = workerCountOf(c); 
                   if (wc >= CAPACITY ||
                       wc >= (core ? corePoolSize : maximumPoolSize)) //判断线程数量是否<maximumPoolSize,是则新增一个Worker线程
                       return false;
                   if (compareAndIncrementWorkerCount(c)) 
                       break retry;
                   c = ctl.get();  
                   if (runStateOf(c) != rs)
                       continue retry;
               }
           }
           boolean workerStarted = false;
           boolean workerAdded = false;
           Worker w = null;
           try {
               w = new Worker(firstTask);//创建一个Worker线程
               final Thread t = w.thread;
               if (t != null) {
                   final ReentrantLock mainLock = this.mainLock;
                   mainLock.lock();//获取全局独占锁
                   try {
                       int rs = runStateOf(ctl.get());
                       if (rs < SHUTDOWN ||
                           (rs == SHUTDOWN && firstTask == null)) {
                           if (t.isAlive()) 
                               throw new IllegalThreadStateException();
                           workers.add(w); //添加线程到workers列表中
                           int s = workers.size();
                           if (s > largestPoolSize)
                               largestPoolSize = s;
                           workerAdded = true;
                       }
                   } finally {
                       mainLock.unlock();//释放全局独占锁
                   }
                   if (workerAdded) {
                       t.start(); //启动线程
                       workerStarted = true;
                   }
               }
           } finally {
               if (! workerStarted)
                   addWorkerFailed(w); //线程新增失败,需要移除
           }
           return workerStarted;
       }
    
         //线程新增失败
         private void addWorkerFailed(Worker w) {
           final ReentrantLock mainLock = this.mainLock;
           mainLock.lock();//获取全局独占锁
           try {
               if (w != null)
                   workers.remove(w);//从workers列表中移除当前worker
               decrementWorkerCount();//减少线程数量
               tryTerminate();//尝试停止一个空闲线程
           } finally {
               mainLock.unlock();//释放全局独占锁
           }
       }
}
线程结束

线程结束执行processWorkerExit方法

public class ThreadPoolExecutor extends AbstractExecutorService {
     private void processWorkerExit(Worker w, boolean completedAbruptly) {
        if (completedAbruptly)  
            decrementWorkerCount();//减少线程数量
   
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock(); //获取全局独占锁
        try {
            completedTaskCount += w.completedTasks;
            workers.remove(w);//从workers列表中移除当前worker
        } finally {
            mainLock.unlock();//释放全局独占锁
        }
        tryTerminate(); //尝试停止一个空闲线程
        int c = ctl.get();
        if (runStateLessThan(c, STOP)) {
            if (!completedAbruptly) {  //计算最小要求线程数,防止出现队列中有任务,但是没有可用的线程的情况
                int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
                if (min == 0 && ! workQueue.isEmpty())
                    min = 1;
                if (workerCountOf(c) >= min)
                    return; 
            }
            addWorker(null, false);//当前线程数<最小要求线程数,新增一个线程
        }
     }
}
修改参数
public class ThreadPoolExecutor extends AbstractExecutorService {
       private void interruptIdleWorkers() {
           interruptIdleWorkers(false); //尝试中断所有空闲线程
       }

       //修改corePoolSize
       public void setCorePoolSize(int corePoolSize) {
           if (corePoolSize < 0)
               throw new IllegalArgumentException();
           int delta = corePoolSize - this.corePoolSize; //与设置前corePoolSize差值
           this.corePoolSize = corePoolSize;
           if (workerCountOf(ctl.get()) > corePoolSize) //当前线程数>corePoolSize
               interruptIdleWorkers();                  //尝试停止所有空闲线程
           else if (delta > 0) {                        //corePoolSize增大
               int k = Math.min(delta, workQueue.size());
               while (k-- > 0 && addWorker(null, true)) { //新增delta个线程
                   if (workQueue.isEmpty())
                       break;
               }
           }
       }

       //修改maximumPoolSize
       public void setMaximumPoolSize(int maximumPoolSize) {
           if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize)
               throw new IllegalArgumentException();
           this.maximumPoolSize = maximumPoolSize;
           if (workerCountOf(ctl.get()) > maximumPoolSize) //当前线程数>maximumPoolSize
               interruptIdleWorkers(); //尝试停止所有空闲线程
       }
}
关闭线程池
public class ThreadPoolExecutor extends AbstractExecutorService {
   //关闭线程池,任务队列中的任务将继续执行
   public void shutdown() {
      final ReentrantLock mainLock = this.mainLock;
      mainLock.lock();
      try {
          checkShutdownAccess();
          advanceRunState(SHUTDOWN);//设置线程池状态为SHUTDOWN
          interruptIdleWorkers();//中断所有空闲线程
          onShutdown(); 
      } finally {
          mainLock.unlock();
      }
      tryTerminate();
   }

   //关闭线程池,任务队列中的任务将不被执行
   public List<Runnable> shutdownNow() {
      List<Runnable> tasks;
      final ReentrantLock mainLock = this.mainLock;
      mainLock.lock();
      try {
          checkShutdownAccess();
          advanceRunState(STOP); //设置线程池状态为STOP
          interruptWorkers(); //中断所有已经开始执行的线程
          tasks = drainQueue();//获取任务列表中的任务,这些任务都不会被执行了
      } finally {
          mainLock.unlock();
      }
      tryTerminate();//尝试关闭一个空闲线程
      return tasks;
   } 
   private void interruptWorkers() {
      final ReentrantLock mainLock = this.mainLock;
      mainLock.lock();
      try {
          for (Worker w : workers)
              w.interruptIfStarted(); //中断已经开始执行的线程
      } finally {
          mainLock.unlock();
      }
   }
   void interruptIfStarted() {
      Thread t;
      if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) { //state!=-1(-1是锁的初始化状态)
          try {
              t.interrupt();//中断线程
          } catch (SecurityException ignore) {
          }
      }
   }
}
  1. shutdown方法会继续执行已加入任务队列的任务,但不能提交新的任务
  2. shutdownNow既不会在执行已加入任务队列的任务,也会尝试中断已经在执行中的任务,也不能提交新的任务
  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值