线程池常用的 四中线程池
1、newSingleThreadExecutor 只创建一个线程的线程池 如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行
源码如下
public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
下面是重载方法 多了一个 线程工厂
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), threadFactory)); }
可以看到阻塞队列依然是 LinkedBlockingQueue;
***并且最重要的是 他返回的是 FinalizableDelegatedExecutorService类型 可以通过名字看出 作用是 确保在收集垃圾时关闭线程池。下面是FinalizableDelegatedExecutorService源码
static class FinalizableDelegatedExecutorService extends DelegatedExecutorService { FinalizableDelegatedExecutorService(ExecutorService executor) { super(executor); } protected void finalize() { super.shutdown(); } }
2、newFixedThreadPool 上次已经解读过 不再赘述
3、newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程
源码如下
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
可以看出 其阻塞队列是 SynchronousQueue 是有线程锁的队列 所以性能会降低 也没有线程数量的限制
4、newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行 有点定时任务的意味 功能很强大。。
public static ScheduledExecutorService newScheduledThreadPool( int corePoolSize, ThreadFactory threadFactory) { return new ScheduledThreadPoolExecutor(corePoolSize, threadFactory); }
可以看出返回的是 ScheduledThreadPoolExecutor 类型 ScheduledThreadPoolExecutor 是ThreadPoolExecutor的子类 并且实现ExecutorService 增加了一些任务调度的方法
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) { if (command == null || unit == null) throw new NullPointerException(); if (delay <= 0) throw new IllegalArgumentException(); ScheduledFutureTask<Void> sft = new ScheduledFutureTask<Void>(command, null, triggerTime(initialDelay, unit), unit.toNanos(-delay)); RunnableScheduledFuture<Void> t = decorateTask(command, sft); sft.outerTask = t; delayedExecute(t); return t; }
可以看出 只有当前任务完成才启动下一个任务,否则等上一个任务完成