线程池的工作原理

ThreadPoolExecutor执行execute方法分下面4种情况

ThreadPoolExecutor执行execute方法分下面4种情况: 

  1. 如果当前运行的线程少于corePoolSize,则创建新线程来执行任务(注意,执行这一步骤 需要获取全局锁)。 
  2. 如果运行的线程等于或多于corePoolSize,则将任务加入BlockingQueue。 
  3. 如果无法将任务加入BlockingQueue(队列已满),则创建新的线程来处理任务(注意,执行这一步骤需要获取全局锁)。
  4. 如果创建新线程将使当前运行的线程超出maximumPoolSize,任务将被拒绝,并调用 RejectedExecutionHandler.rejectedExecution()方法。 

ThreadPoolExecutor采取上述步骤的总体设计思路,是为了在执行execute()方法时,尽可能 地避免获取全局锁(那将会是一个严重的可伸缩瓶颈)。在ThreadPoolExecutor完成预热之后 (当前运行的线程数大于等于corePoolSize),几乎所有的execute()方法调用都是执行步骤2,而步骤2不需要获取全局锁。

attachments-2020-11-qHnOv1zD5fb6378f3271e.png ThreadPoolExecutor执行示意图

//execute源码
public void execute(Runnable command) {
	if (command == null)
	int c = ctl.get();
	//如果线程数小于基本线程数
	if (workerCountOf(c) < 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))
        //抛出RejectedExecutionException异常
		reject(command);
}

attachments-2020-11-UDaSaHUz5fb637b708438.png


  • 发表于 2020-11-19 17:15
  • 阅读 ( 23 )

0 条评论

请先 登录 后评论
热爱技术的小仓鼠
热爱技术的小仓鼠

145 篇文章

作家榜 »

  1. NX小编 1233 文章
  2. 58沈剑 311 文章
  3. 热爱技术的小仓鼠 145 文章
  4. 奈学教育 139 文章
  5. 李希沅 | 奈学教育 41 文章
  6. 江帅帅 | 奈学教育 29 文章
  7. 林淮川 | 奈学教育 12 文章
  8. 邱鹏超 3 文章