java线程池——ThreadPoolExecutor源码解析

在Java中,咱们常常使用的线程池就是ThreadPoolExecutor,此外还有定时的线程池ScheduledExecutorService(),可是须要注意的是Executors.newCachedThreadPool()的线程是没有上届的,在使用时,须要注意,由于没有办法控制线程数量,可能会致使线程的溢出。
一个简单的示例函数

clipboard.png

1 ThreadPoolExecutor提供了四个构造函数:
//五个参数的构造函数
public ThreadPoolExecutor(int corePoolSize,spa

int maximumPoolSize,
                      long keepAliveTime,
                      TimeUnit unit,
                      BlockingQueue<Runnable> workQueue)

//六个参数的构造函数
public ThreadPoolExecutor(int corePoolSize,线程

int maximumPoolSize,
                      long keepAliveTime,
                      TimeUnit unit,
                      BlockingQueue<Runnable> workQueue,
                      ThreadFactory threadFactory)

//六个参数的构造函数
public ThreadPoolExecutor(int corePoolSize,code

int maximumPoolSize,
                      long keepAliveTime,
                      TimeUnit unit,
                      BlockingQueue<Runnable> workQueue,
                      RejectedExecutionHandler handler)

//七个参数的构造函数
public ThreadPoolExecutor(int corePoolSize,对象

int maximumPoolSize,
                      long keepAliveTime,
                      TimeUnit unit,
                      BlockingQueue<Runnable> workQueue,
                      ThreadFactory threadFactory,
                      RejectedExecutionHandler handler)

2 各个参数解释接口

  • int corePoolSize:该线程池中核心线程数最大值。

核心线程:线程池新建线程的时候,若是当前线程总数小于corePoolSize,则新建的是核心线程,若是超过corePoolSize,则新建的线程即为非核心线程,核心线程默认状况下会一直存在线程池中,即便这个线程什么也不干,若是指定ThreadPoolExecutor的allowCoreThreadTimeOut这个属性是true,那么核心线程若是长时间不干活的话,超过必定时间,就会被销毁掉。队列

  • int maximumPoolSize:该线程池中线程的最大值
  • long keepAliveTime :该线程池中非核心线程闲置超时时间

一个非核心线程,若是不干活的时间超过这个参数所设定的时长,就会被销毁,若是设置allowCoreThreadTimeOut = true,那么核心线程超过所设定的时长,那么也会销毁掉。ip

  • TimeUnit unit:keepAliveTime的单位

TimeUnit是一个枚举类型,其包括:NANOSECONDS : 1微毫秒 = 1微秒 / 1000,MICROSECONDS : 1微秒 = 1毫秒 / 1000,MILLISECONDS : 1毫秒 = 1秒 /1000,
SECONDS : 秒,MINUTES : 分,HOURS : 小时,DAYS : 天。it

  • BlockingQueue workQueue:该线程池中的任务队列:维护等待执行的Runnable对象。

若是当全部的核心线程都在干活时,新添加的任务会被添加到这个队列中等待处理,若是队列满了,则新建非核心的线程执行任务。经常使用的workQueue类型。io

    • SynchronousQueue:这个队列接收到任务的时候,会直接提交给线程处理,而不会保留它,若是线程都在工做,那就新建一个线程来处理这个任务,因此为了保证不出现<线程数达到了maximumPoolSize而不能新建线程>的错误,使用这个类型队列的时候,maximumPoolSize通常指定成Integer.MAX_VALUE,即无限大。
    • LinkedBlockingQueue:这个队列接收到任务的时候,若是线程小于核心线程,则新建核心线程来处理任务,若是当前线程等于核心线程数,则进入队列中等待。因为这个队列没有最大值限制,即全部超过核心线程数的任务都会被添加到队列中去,这也致使maximumPoolSize的设定失效,由于总线程数永远不会超过corePoolSize
    • ArrayBlockingQueue:能够设定队列的长度,接收到任务的时候,若是没有达到corePoolSize的值,则新建线程执行任务,若是达到了,则入队等候,若是队列已满,则新建线程执行任务,若是线程数到了maximumPoolSize,而且队列中也满了,则发生错误。
    • DelayQueue:队列中元素必须实现Delayed接口,这就意味着你传进去的任务必须实现

Delayed接口,这个队列接收到任务时,首先先入队,只有达到指定的延时时间,才会执行任务。

    • ThreadFactory threadFactory:建立线程的方式,这是一个接口,你new它的时候须要实现它的Thread newThread(Runnable r)方法,通常用不上。
    • RejectedExecutionHandler handler:这玩意儿就是抛出异常专用的,好比上面提到的两个错误发生了,就会由这个handler抛出异常,根本用不上。

3 经常使用API解释:

  • public void execute(Runnable command)

未来某个时候执行给定的任务。任务能够在新线程中执行,也能够在现有的池线程中执行。若是没法提交任务以供执行,或者由于该执行器已经关闭,或者由于其容量已经达到,则该任务由当前{RejectedExecutionHandler}处理。

  • public void shutdown()

将线程池状态置为SHUTDOWN,并不会当即中止,中止接收外部submit的任务,内部正在跑的任务和队列里等待的任务,会执行完,才真正中止。

  • public List<Runnable> shutdownNow()

将线程池状态置为STOP。企图当即中止,事实上不必定,跟shutdown()同样,先中止接收外部提交的任务,忽略队列里等待的任务,尝试将正在跑的任务interrupt中断,返回未执行的任务列表。

  • public boolean awaitTermination(long timeout, TimeUnit unit)

当前线程阻塞,直到等全部已提交的任务(包括正在跑的和队列中等待的)执行完,或者等超时时间到,或者线程被中断,抛出InterruptedException,而后返回true(shutdown请求后全部任务执行完毕)或false(已超时)。

相关文章
相关标签/搜索