1 类ThreadPoolExecutor
主要参数:
- corePoolSize 核心线程数,空闲的时候保持的线程数量
- maximumPoolSize 当核心线程数用完了,任务队列也用完了以后能增加的最大线程的数量
- keepAliveTime 非核心线程存活的时间
- workQueue 阻塞队列 [问题?为什么用阻塞队列,因为线程安全吗?]
- threadFactory
- handler 拒绝策略(4种,丢弃,丢弃最长的,抛出异常,用提交线程执行)
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler
2 Executors.newFixedThreadPool
核心线程数和最大线程数相等,存活的时间为0,使用阻塞的队列为LinkedBlockingQueue 注意这里的泛型类型为Runnable,也就是无论提交了啥Runnable还是Callable都是按照线程基本的运行方式来进行运行,即运行Runnable.run()
new ThreadPoolExecutor(nThreads,
nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
3 Executors.newSingleThreadExecutor()
单线程的线程池,任务队列无限大,任何时刻都只有一个线程在线程池里面,当里面的线程出现问题的时候,能够创建新的线程来执行任务
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
4 Executors.newCachedThreadPool()
注意这里使用的任务队列SynchronousQueue()表示每一个时刻只有当有其他线程来取的时候,才能插入;所以每个时候插入任务到该队列中都会失败,而核心线程数量为0,所以去创建新的线程执行线程。
适用场景:线程池停顿时间长,任务执行时间短。因为线程池里面的线程很快会被回收,所以不消耗任何资源。
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
5 Executors.newScheduledThreadPool
创建一个可以延迟执行任务或者定时任务
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}