关于线程池的理解
线程池
在项目中提前创建好几个线程,当有任务来的时候,直接用创建好的线程来处理任务,处理完之后,线程不会销毁,等待下一个任务。由于创建和销毁线程很消耗性能。所以可以用线程池来提高性能。
自己踏入过的误区,在一个类里面,把线程池当作了改类的成员变量,用完之后没有shutdown。
eg:
// 错误写法
public class test{
private ThreadPoolExecutor excutor
......
}
每次新建改对象,都会创建一个线程池,这样会导致资源耗尽,出现OOM。
误区2 ,在一个类中,设置一个静态变量的线程池,这个类共用一个线程池。用完之后没有shutdown。
eg:
// 错误写法
public class test{
private static ThreadPoolExecutor excutor
......
}
这样的写法有点狭隘,只在当前类中,浪费资源。
正确写法,在整个项目中,提供一个util的线程池,整个项目使用一个线程池
eg:
public class ThreadPoolExecutorUtil{
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(10,20,
60L,TimeUnit.SECONDS,
new SynchronousQueue<>(),Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
public static ThreadPoolExecutor getInstance(){
return executor;
}
}
参数介绍
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
- corePoolSize : 核心池大小,线程池允许的线程数量
- maximumPoolSize:最大池大小,当核心池中的线程数量满了,并且BlockingQueue队列已满,这个时候又来了一个任务。就会新建一个线程执行该任务,一直到线程池的线程数量达到maximumPoolSize大小,如果这时再来一个任务,就会调用相应的拒绝策略。当线程池的任务降低到只需要corePoolSize的线程数一下,就会根据keepAliveTime ,回收大于corePoolSize的多余的线程。
- keepAliveTime:当线程池中的数据大于corePoolSize时,多余的线程没有任务进来的时候,根据这个时间大小回收。
- unit:回收时间大小
- workQueue:阻塞队列类型
- threadFactory:线程池工程
- handler:拒绝策略
创建线程池
阿里巴巴开发者手册中有些写到:
所以正确的创建方式
private static ThreadPoolExecutor executor = new ThreadPoolExecutor(10,20,
60L,TimeUnit.SECONDS,
new SynchronousQueue<>(),Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());