目录
本篇精华使用方式
ExecutorService threadPool = new ThreadPoolExecutor(1, 5, 30, TimeUnit.MILLISECONDS,
new LinkedBlockingDeque<Runnable>(1024), Executors.defaultThreadFactory(),
Executors.defaultThreadFactory()
new ThreadPoolExecutor.AbortPolicy());
threadPool.execute(() -> {
try {
handlerMappingSummaryJobRunnable.run();//执行 方法
} catch (Exception e) {
e.printStackTrace();
}finally{
threadPool.shutdown();// 关闭线程池
}
});
对应线程池参数
- corePoolSize 核心线程池大小
- maximumPoolSize 线程池最大容量大小
- keepAliveTime 线程池空闲时,线程存活的时间
- TimeUnit 时间单位
- BlockingQueue任务队列–LinkedBlockingDeque是双向链表实现的双向并发阻塞队列。该阻塞队列同时支持FIFO和FILO两种操作方式,即可以从队列的头和尾同时操作(插入/删除);并且,该阻塞队列是支持线程安全。
- ThreadFactory 线程工厂,Executors.defaultThreadFactory(),也可以使用下面的
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("demo-pool-%d").build();
- RejectedExecutionHandler 线程拒绝策略
new thread创建线程-1
public void doSummaryJob() throws Exception {
try{
HandlerMappingSummaryJobRunnable handlerMappingSummaryJobRunnable = new HandlerMappingSummaryJobRunnable();
Thread summaryJobThread = new Thread(handlerMappingSummaryJobRunnable);
summaryJobThread.start();
}catch(Exception e){
throw new Exception(HandlerMappingStaticValue.LOG_DO_SUMMARY_JOB_ERROR+e.getMessage());
}
}
new thread创建线程-2(lambda表达式)
Thread thread1 = new Thread(()->{
System.out.println("hello world");
});
- 优势:显而易见的线程创建方式
- 缺点:每次都要new对象,当有大量请求时,数不清new了多少个对象了,如果不及时关闭会导致内存溢出,因此还要考虑线程管理等问题。
Executors工厂创建线程池
HandlerMappingSummaryJobRunnable handlerMappingSummaryJobRunnable = new HandlerMappingSummaryJobRunnable();
// 定义一个线程池
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(() -> {
try {
handlerMappingSummaryJobRunnable.run();//执行 方法
} catch (Exception e) {
e.printStackTrace();
}finally{
executor.shutdown();// 关闭线程池
}
Executors工厂创建线程池分析
- newCachedThreadPool:
- 创建一个可缓存线程池
- 优点:很灵活,弹性的线程池线程管理,用多少线程给多大的线程池,不用后及时回收,用则新建
- 缺点:一旦线程无限增长,会导致内存溢出。
- newFixedThreadPool :
优点:创建一个固定大小线程池,超出的线程会在队列中等待。
缺点:不支持自定义拒绝策略,大小固定,难以扩展 - newScheduledThreadPool :
优点:创建一个固定大小线程池,可以定时或周期性的执行任务。
缺点:任务是单线程方式执行,一旦一个任务失败其他任务也受影响 - newSingleThreadExecutor :
优点:创建一个单线程的线程池,保证线程的顺序执行
缺点:不适合并发。。不懂为什么这种操作要用线程池。。为什么不直接用队列 - 统一缺点:不支持自定义拒绝策略。
- Java通过Executors提供四种线程池,分别为:
1)newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
2)newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
3)newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
4)SingleThreadPool 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
Executors返回的线程池对象的弊端如下:
1)FixedThreadPool 和 SingleThreadPool:
允许的请求队列长度为Integer.MAX_VALUE,可能会堆积大量的请求,从而导致OOM。
2)CachedThreadPool 和 ScheduledThreadPool :
允许创建的线程数量为Integer.MAX_VALUE,可能会创建大量的线程,从而导致OOM。
ThreadPoolExecutor创建线程
ExecutorService threadPool = new ThreadPoolExecutor(1, 5, 30, TimeUnit.MILLISECONDS,
new LinkedBlockingDeque<Runnable>(1024), Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
threadPool.execute(() -> {
try {
handlerMappingSummaryJobRunnable.run();//执行 方法
} catch (Exception e) {
e.printStackTrace();
}finally{
threadPool.shutdown();// 关闭线程池
}
});
ThreadPoolExecutor构造器参数解析
public ThreadPoolExecutor(
int corePoolSize, - 线程池核心池的大小。
int maximumPoolSize, - 线程池的最大线程数。
long keepAliveTime, - 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
TimeUnit unit, - keepAliveTime 的时间单位。
BlockingQueue<Runnable> workQueue, - 用来储存等待执行任务的队列。
ThreadFactory threadFactory, - 线程工厂。
RejectedExecutionHandler handler) - 拒绝策略。
)