作者:@stars-one

本文为作者原创,转载请注明出处:https://www.cnblogs.com/kexing/p/11946197.html


有点笨,参考了好几篇大佬们写的文章才整理出来的笔记....

字面意思上解释,线程池就是装有线程的池,我们可以把要执行的多线程交给线程池来处理,和连接池的概念一样,通过维护一定数量的线程池来达到多个线程的复用。

好处

多线程产生的问题

一般我们使用到多线程的编程的时候,需要通过new Thread(xxRunnable).start()创建并开启线程,我们可以使用多线程来达到最优效率(如多线程下载)。

但是,线程不是越多就越好,线程过多,创建和销毁就会消耗系统的资源,也不方便管理。

除此之外,多线程还会造成并发问题,线程并发数量过多,抢占系统资源从而导致阻塞。

线程池优点

我们将线程放入线程池,由线程池对线程进行管理,可以对线程池中缓冲的线程进行复用,这样,就不会经常去创建和销毁线程了,从而省下了系统的资源。

线程池能够有效的控制线程并发的数量,能够解决多线程造成的并发问题。

除此之外,线程池还能够对线程进行一定的管理,如延时执行、定时循环执行的策略等

线程池实现

线程池的实现,主要是通过这个类ThreadPoolExecutor,其的构造参数非常长,我们先大概了解,之后再进行详细的介绍。

public ThreadPoolExecutor(int corePoolSize,     int maximumPoolSize,long keepAliveTime,     TimeUnit unit,BlockingQueue workQueue,     RejectedExecutionHandler handler)
  • corePoolSize:线程池核心线程数量
  • maximumPoolSize:线程池最大线程数量
  • keepAliverTime:当活跃线程数大于核心线程数时,空闲的多余线程最大存活时间
  • unit:存活时间的单位
  • workQueue:存放线程的工作队列
  • handler:超出线程范围和队列容量的任务的处理程序(拒绝策略)

这里大概简单说明一下线程池的运行流程:

当线程被添加到线程池中,如果线程池中的当前的线程数量等于线程池定义的最大核心线程数量(corePoolSize)了,此线程就会别放入线程的工作队列(workQueue)中,等待线程池的调用。

Java提供了一个工具类Excutors,方便我们快速创建线程池,其底层也是调用了ThreadPoolExecutor

不过阿里巴巴Java规范中强制要求我们应该通过ThreadPoolExecutor来创建自己的线程池,使用Excutors容易造成OOM问题。

所以,我们先从Excutors开始学习,之后在对ThreadPoolExecutor进行详细的讲解

Excutors

由于Excutors是工具类,所以下面的介绍的都是其的静态方法,如果是比较线程数目比较少的小项目,可以使用此工具类来创建线程池

PS:把线程提交给线程池中,有两种方法,一种是submit,另外一种则是execute

两者的区别: