关于线程池的原理

参考这篇https://blog.csdn.net/he90227/article/details/52576452,具体的源码实现太多,也容易乱,仅捋出来核心的思路在这里总结:

线程池的目的

  • 我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题:

  • 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间。

  • 那么有没有一种办法使得线程可以复用,就是执行完一个任务,并不被销毁,而是可以继续执行其他的任务?

  • 在Java中可以通过线程池来达到这样的效果。

线程池如何工作

核心方法execute(Runnable runnable),意思是提交任务给线程池进行处理
这里写图片描述
对于上图的解释:

* 如果正在运行的线程数量小于 corePoolSize,那么马上创建线程运行这个任务;   
* 如果正在运行的线程数量大于或等于 corePoolSize,那么将这个任务放入队列;
* 如果这时候队列满了,而且正在运行的线程数量小于 maximumPoolSize,那么还
是要创建非核心线程立刻运行这个任务;
* 如果队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线
程池会抛出异常RejectExecutionException。

核心线程未满 = 正在运行的线程数

 1)ArrayBlockingQueue:
 基于数组的先进先出队列,此队列创建时必须指定大小;

2)LinkedBlockingQueue:基于链表的先进先出队列,
如果创建时没有指定此队列大小,则默认为Integer.MAX_VALUE;

3)synchronousQueue:这个队列比较特殊,它不会保存
提交的任务,而是将直接新建一个线程来执行新来的任务。

另外
注意两点

  • 如果当前线程池中的线程数目>=corePoolSize,则每来一个任务,会尝试将其添加到任务缓存队列当中,若添加成功,则该任务会等待空闲线程将其取出去执行;若添加失败(一般来说是任务缓存队列已满),则会尝试创建新的线程去执行这个任务;
  • 如果线程池中的线程数量大于corePoolSize时,如果某线程空闲时间超过keepAliveTime(这说明任务缓存队列为空呗),线程将被终止,直至线程池中的线程数目不大于corePoolSize;如果允许为核心池中的线程设置存活时间,那么核心池中的线程空闲时间超过keepAliveTime,线程也会被终止。

以上是基本上线程池维护的基本运行逻辑,具体细节还请看作文原文

猜你喜欢

转载自blog.csdn.net/weixin_38719347/article/details/82023049
今日推荐