Executors
线程池的工具类:
Factory and utility methods for Executor, ExecutorService, ScheduledExecutorService, ThreadFactory, and Callable classes defined in thispackage. This class supports the following kinds of methods:
- Methods that create and return an {@link ExecutorService} set up with commonly useful configuration settings.
- Methods that create and return a {@link ScheduledExecutorService} set up with commonly useful configuration settings.
- Methods that create and return a "wrapped" ExecutorService, that disables reconfiguration by making implementation-specific methods inaccessible.
- Methods that create and return a {@link ThreadFactory} that sets newly created threads to a known state.
- Methods that create and return a {@link Callable} out of other closure-like forms, so they can be used in execution methods requiring {@code Callable}.
@since 1.5
@author Doug Lea
翻译:Executors是工具类,为Executor、ExecutorService、ScheduledExecutorService、ThreadFactory、Callable类提供了静态方法。这个类支持以下方法:
- 使用常用的配置去实例 ExecutorService 并返回其对象
- 使用常用的配置去实例 ScheduledExecutorService 并返回其对象
- 实例 ThreadFactory 并返回其对象, 创建出来的线程不是守护线程,并且优先等级
Thread.NORM_PRIORITY...
Executors.newFixedThreadPool(int nThread)
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>())
;
}
核心线程数量和最大线程数量相同,说明不会开辟非核心线程
使用 LinkedBlockingQueue 这是一个大小`Integer.MAX_VALUE`的阻塞队列。 这也说明了无论怎样都不会开辟非核心线程。
但是这是非常危险的事,在高并发下随时会来上百万的任务,这样直接就 OOM 了
Executors.newSingleThreadExecutor()
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1,
1,
0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable());
}
很明显,这用线程池创建了单线程。
而且任务队列与固定大小线程池相同,很容易 oom
Executors.newCachedThreadPool()
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0,
Integer.MAX_VALUE,
60L,
TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
所有的线程都是非核心线程,
使用的队列是同步队列。这个队列的特点是容量只有1。
满了的话put的线程会阻塞。
空了的话take的线程也会阻塞。
还有一点,虽然这是队列但是得到的实例默认是一个栈
public SynchronousQueue(boolean fair) {
transferer = fair ? new TransferQueue<E>() : new TransferStack<E>();
}
fair默认是false
ThreadPoolExecutor
建议直接实例化 ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler) {
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
主要点:任务队列和拒绝策略
BlockingQueue 的实现类主要有4个
ArrayBlockingQueue 最常使用
DelayQueue
LinkedBlockingQueue
SynchronousQueue
根据需求使用,当然我们也可以实现BlockingQueue接口,但是略麻烦
拒绝策略 的实现了也是四个
AbortPolicy 抛出异常(默认)
CallerRunsPolicy 任务提交者自己执行
DiscardOldestPolicy 抛弃任务队列的头部任务
DiscardPolicy 什么都不做
根据需要我们也可以通过实现 RejectedExecutionHandler 接口来自定义拒绝策略。