ThreadPoolExecutor 各个参数详解

线程池
#1

ThreadPoolExecutor 各个参数详解

ThreadPoolExecutor 的构造方法

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

corePoolSize

线程的核心线程数量

maximumPoolSize

线程池的最大线程数量

keepAliveTime

空闲线程的存活时间值

timeUnit

空闲线程的存活时间单位

blockingQueue

任务队列

threadFactory

线程工厂实现

handler

线程池无法执行任务时的拒绝策略

这些参数有什么关系?

其实到现在蛮多人都还鼓捣不清楚

  • 当线程池收到新任务的试试,会判断当前线程池的线程数量是否小于 corePoolSize

    • 小于:新建线程执行任务,哪怕是还有空闲线程,也会新建一个线程来执行任务
    • 等于:任务队列是否有空位
      • 有:把任务push到任务队列
      • 没:判断,当前线程数量是否小于 maximumPoolSize
        • 小于:创建新的线程来执行任务
        • 等于:执行 handler 拒绝策略
  • 超出了 corePoolSize 创建的那些线程,会在空闲一定的时间后被回收

  • 空闲的时间,就是由 keepAliveTime + timeUnit 控制的

blockingQueue

BlockingQueue<Runnable> workQueue

// 实现
ArrayBlockingQueue
LinkedBlockingQueue
ConcurrentLinkedQueue
LinkedTransferQueue
PriorityBlockingQueue
DelayQueue
SynchronousQueue
...

存放任务的队列,可选的实现非常多。可以根据应用的场景去选择。但是要注意,如果选择了无界队列。例如底层是链表实现的队列,它不存在 装满 这个概念。根据上述的执行逻辑,所以你的push到线程池的所有的任务都会被它接受。不会触发 RejectedExecutionHandler 。同样的,keepAliveTimetimeUnit 也就失去了意义

RejectedExecutionHandler

拒绝策略的接口

public interface RejectedExecutionHandler {
    void rejectedExecution(Runnable r, ThreadPoolExecutor executor);
}

在 ThreadPoolExecutor 内部有几个预定义的实现

AbortPolicy

抛出异常

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
	throw new RejectedExecutionException("Task " + r.toString() + " rejected from " +  e.toString());
 }
CallerRunsPolicy

在当前线程下直接新启动一个线程来执行

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
	if (!e.isShutdown()) {
		r.run();
	}
}
DiscardOldestPolicy

抛弃队列中最老的任务,然后push当前任务到队列

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    if (!e.isShutdown()) {
	    e.getQueue().poll();
	    e.execute(r);
    }
}
DiscardPolicy

不做任何处理,抛弃当前任务

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
}

ThreadFactory

线程池工厂,用于自定义线程的实现
例如,可以自己给线程添加自定义的前缀名称。(极有用,在排除线程问题的时候,需要一个合适的命名)

public interface ThreadFactory {
    Thread newThread(Runnable r);
}