在开发中我们会使用到线程,而为了减少资源的损耗,提高性能,我们一般会使用线程池。线程池具有重用存在的线程,减少对象创建、消亡的开销,性能佳, 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞,提供定时执行、定期执行、单线程、并发数控制等功能。那么线程池是怎么执行的呢,我们来分析一下:
要了解线程池的执行过程,我们需要知道线程池是怎么创建的,现在我们来说其中一种:
从上面的构造方法中可以看出,线程池的创建是定义了相关的概念的,那么线程池是如何提交任务的呢,当线程池创建完毕之后,要提交任务,需要调用它里面的excute方法进行提交:
[Java] 纯文本查看 复制代码 public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
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))
//创建线程失败,说明线程池关闭或者完全满了,拒绝任务
reject(command);
}
可以看到,线程池处理一个任务主要分三步处理,代码注释里已经介绍了。现在我们使用图片来理解一下:
从图中我们可以看到,向线程池提交任务时,会首先判断线程池中的线程数是否大于设置的核心线程数,如果不大于,就创建一个核心线程来执行任务。
如果大于核心线程数,就会判断缓冲队列是否满了,如果没有满,则放入队列,等待线程空闲时执行任务。
如果队列已经满了,则判断是否达到了线程池设置的最大线程数,如果没有达到,就创建新线程来执行任务。
如果已经达到了最大线程数,则执行指定的拒绝策略。
|