在业务场景中,如果一个对象创建销毁开销比较大, 那么此时建议池化对象进行管理,例如线程,jdbc连接等等,在高并发场景中,如果可以复用之前销毁的对象,那么系统效率将大大提升。另外一个好处是可以设定池化对象的上限,例如预防创建线程数量过多导致系统崩溃的场景。
下文主要从以下几个角度讲解:
创建线程池
我们可以通过自定义ThreadPoolExecutor或者jdk内置的Executors来创建一系列的线程池
上述几种都是通过new ThreadPoolExecutor()来实现的, 构造函数源码如下:
/**
* @param corePoolSize 池内核心线程数量, 超出数量的线程会进入阻塞队列
* @param maximumPoolSize 最大可创建线程数量
* @param keepAliveTime 线程存活时间
* @param unit 存活时间的单位
* @param workQueue 线程溢出后的阻塞队列
*/
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler);
}
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}
public static ExecutorService newSingleThreadExecutor() {
return new Executors.FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()));
}
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
}
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS, new ScheduledThreadPoolExecutor.DelayedWorkQueue());
}
提交任务
直接调用executorService.execute(runnable)或者submit(runnable)即可,
我们看下newScheduledThreadPool的使用示例.
public class SchedulePoolDemo {
public static void main(String[] args){
ScheduledExecutorService service = Executors.newScheduledThreadPool(10);
// 如果前面的任务没有完成, 调度也不会启动
service.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(2000);
// 每两秒打印一次.
System.out.println(Sy