线程池的创建多种方式
什么是线程池?
将多个线程放在一个容器内,当任务出现和结束时,只需要从线程池拿取和放入线程。避免线程的重复创建和销毁
优点:
- 提高资源利用率
- 提高响应速度
- 提高线程的管理
自定义线程池创建
ThreadPoolExecutor
- int corePoolSize,
- int maximumPoolSize,
- long keepAliveTime,
- TimeUnit unit,
- BlockingQueue<Runnable> workQueue,
- ThreadFactory threadFactory,
- RejectedExecutionHandler handler
各自参数的含义
int corePoolSize 核心线程数,线程中始终存活的线程数
int maximumPoolSize 最大线程数,线程池中允许的最大线程数,当线程池的任务队列满之后可以创建的最大线程数
long keepAliveTime 最大线程数可以存活的时间,当线程中没有任务执行时,最大线程就会销毁一部分,最终保持核心线程数量的线程
TimeUnit unit keepAliveTime的单位(TimeUnit.XXX)
BlockingQueue<Runnable> workQueue 阻塞队列,存储线程池等待执行的任务。
有以下几种队列类型:
ArrayBlockingQueue: 数组结构组成的有界阻塞队列
LinkedBlockingQueue:链表结构组成的有界阻塞队列
SynchronousQueue:不存储元素的阻塞队列,直接提交给线程不保存它们
PriorityBlockingQueue:支持优先级排序的无界阻塞队列
DelayQueue:使用优先级队列实现的无界阻塞队列,只有在延迟期满时才能从中提取元素
LinkedTransferQueue:由链表结构组成的无界阻塞队列。与SynchronousQueue类似,还含有非阻塞方法
LinkedBlockingDeque:由链表结构组成的双向阻塞队列
ThreadFactory threadFactory 线程工厂,主要用来创建线程
RejectedExecutionHandler handler 拒绝策略,拒绝处理任务时的策略
四种拒绝策略:
AbortPolicy:拒绝并抛出异常
CallerRunsPolicy:使用当前调用的线程来执行此任务
DiscardOldestPolicy:抛弃队列头部的任务(通常存活时间最长),并执行当前任务
DiscardPolicy:忽略并抛弃当前任务
固定线程池
创建一个固定大小的线程池,可控制并发的线程数,超出的线程会在队列中等待
ExecutorService executorService = Executors.newFixedThreadPool(5);
缓存线程池
创建一个可缓存的线程池,若线程数超过处理所需,缓存一段时间后会回收,若线程数不够,则新建线程
ExecutorService executorService = Executors.newCachedThreadPool();
单个线程池
创建单个线程数的线程池,它可以保证先进先出的执行顺序
ExecutorService executorService = Executors.newSingleThreadExecutor();
延迟执行线程池
创建一个可以执行延迟任务的线程池
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
System.out.println("延迟执行前时间:"+new Date());
scheduledThreadPool.schedule(()->{
System.out.println("延迟执行时间:"+new Date());},5L, TimeUnit.SECONDS);
单线程延迟执行线程池
创建一个单线程的可以执行延迟任务的线程池
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
抢占式执行线程池
创建一个抢占式执行的线程池(任务执行顺序不确定),注意此方法只有在 JDK 1.8+ 版本中才能使用
ExecutorService executorService = Executors.newWorkStealingPool();
for (int i = 0; i < 10; i++) {
final int index = i;
executorService.execute(()->{
System.out.println(index+" 被执行,线程名:"+Thread.currentThread().getName());
});
}
while (!executorService.isTerminated()){
}
网友评论