ThreadPoolExecutor构造器 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), handler); }
线程池构造器ThreadPoolExecutor
corePoolSize 线程池核心线程数
线程池创建后,线程池中的线程数为0,当任务过来了就会创建一个线程去执行,当数量达到corePoolSize后,新来的任务会加入到任务队列(BlockingQueue)中,如果任务队列满了,那么会查看当前线程数和最大线程数,如果没有超过则创建新的线程来执行任务,否则交给拒绝策略来处理无法处理的任务,RejectedExecutionHandler.rejectedExecution()。
线程池在线程数没有达到核心线程数时,每次任务执行,都会创建一个新的线程来执行。
maximumPoolSize
最大线程数,当线程池达到核心线程数,任务队列满了,并且线程数已经达到最大线程数了,这时,RejectedExecutionHandler.rejectedExecution()就会拒绝处理任务抛出异常。
keepAliveTime
当线程的空闲时间达到keepAliveTime时,线程会退出,直到线程数=corePoolSize,
如果allowCoreThreadTimeout=true,则会全部退出,直到线程数量为0.
unit
keepAliveTime时间的单位时间
workQueue
保存任务的队列
handler
拒绝处理器,用于在线程池无法处理任务的时候处理操作。
Executors 和 ThreadPoolExecutor.
不允许使用Executors
Executors的 newCachedThreadPool方法,最大线程数是Integer.MAX_VALUE=2147483647这么大,无限制的创建线程,甚至是OOM.
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
newScheduledThreadPool方法,也是使用了Integer.MAX_VALUE
public static ScheduledExecutorService newSingleThreadScheduledExecutor() { return new DelegatedScheduledExecutorService (new ScheduledThreadPoolExecutor(1)); }
public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, Integer.MAX_VALUE, DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS, new DelayedWorkQueue()); }
newSingleThreadExecutor和newFixedThreadPool这两个方法使用了LinkedBlockingQueue这个队列来做任务存储队列。这个任务队列是无边界的,容易产生任务堆积,更容易把内存用完。
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
任务队列的选择:
BlockingQueue队列接口,所有的实现类都是并发安全的队列。分为无界队列和有界队列。
ArrayBlockingQueue
底层是数组实现的有界队列,并发控制采用可重入锁控制,插入读取都需要获取锁。
SynchronousQueue
LinkedBlockingDeque
LinkedBlockingQueue