import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; public class Ch09_Executor { private static void run(ExecutorService threadPool) { for(int i = 1; i < 5; i++) { final int taskID = i; threadPool.execute(new Runnable() { @Override public void run() { for(int i = 1; i < 5; i++) { try { Thread.sleep(20);// 为了测试出效果,让每次任务执行都须要必定时间 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("第" + taskID + "次任务的第" + i + "次执行"); } } }); } threadPool.shutdown();// 任务执行完毕,关闭线程池 } public static void main(String[] args) { // 建立能够容纳3个线程的线程池 ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); // 线程池的大小会根据执行的任务数动态分配 ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); // 建立单个线程的线程池,若是当前线程在执行任务时忽然中断,则会建立一个新的线程替代它继续执行任务 ExecutorService singleThreadPool = Executors.newSingleThreadExecutor(); // 效果相似于Timer定时器 ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3); run(fixedThreadPool); // run(cachedThreadPool); // run(singleThreadPool); // run(scheduledThreadPool); } }
CachedThreadPool会建立一个缓存区,将初始化的线程缓存起来。会终止而且从缓存中移除已有60秒未被使用的线程。java
若是线程有可用的,就使用以前建立好的线程,缓存
若是线程没有可用的,就新建立线程。服务器
// 线程池的大小会根据执行的任务数动态分配 ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, //core pool size Integer.MAX_VALUE, //maximum pool size 60L, //keep alive time TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
执行结果:并发
第1次任务的第1次执行
第4次任务的第1次执行
第3次任务的第1次执行
第2次任务的第1次执行
第3次任务的第2次执行
第4次任务的第2次执行
第2次任务的第2次执行
第1次任务的第2次执行
第2次任务的第3次执行
第4次任务的第3次执行
第3次任务的第3次执行
第1次任务的第3次执行
第2次任务的第4次执行
第1次任务的第4次执行
第3次任务的第4次执行
第4次任务的第4次执行
4个任务是交替执行的。异步
在FixedThreadPool中,有一个固定大小的池。ide
若是当前须要执行的任务超过池大小,那么多出的任务处于等待状态,直到有空闲下来的线程执行任务,源码分析
若是当前须要执行的任务小于池大小,空闲的线程也不会去销毁。测试
// 建立能够容纳3个线程的线程池 ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3); public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, //core pool size nThreads, //maximum pool size 0L, //keep alive time TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
执行结果:spa
第1次任务的第1次执行
第3次任务的第1次执行
第2次任务的第1次执行
第3次任务的第2次执行
第2次任务的第2次执行
第1次任务的第2次执行
第3次任务的第3次执行
第1次任务的第3次执行
第2次任务的第3次执行
第3次任务的第4次执行
第1次任务的第4次执行
第2次任务的第4次执行
第4次任务的第1次执行
第4次任务的第2次执行
第4次任务的第3次执行
第4次任务的第4次执行
建立了一个固定大小的线程池,容量为3,而后循环执行了4个任务。由输出结果能够看到,前3个任务首先执行完,而后空闲下来的线程去执行第4个任务。线程
SingleThreadExecutor获得的是一个单个的线程,这个线程会保证你的任务执行完成。
若是当前线程意外终止,会建立一个新线程继续执行任务,这和咱们直接建立线程不一样,也和newFixedThreadPool(1)不一样。
// 建立单个线程的线程池,若是当前线程在执行任务时忽然中断,则会建立一个新的线程替代它继续执行任务 ExecutorService singleThreadPool = Executors.newSingleThreadExecutor(); public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecutor(1, //core pool size 1, //maximum pool size 0L, //keep alive time TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())); }
执行结果:
第1次任务的第1次执行
第1次任务的第2次执行
第1次任务的第3次执行
第1次任务的第4次执行
第2次任务的第1次执行
第2次任务的第2次执行
第2次任务的第3次执行
第2次任务的第4次执行
第3次任务的第1次执行
第3次任务的第2次执行
第3次任务的第3次执行
第3次任务的第4次执行
第4次任务的第1次执行
第4次任务的第2次执行
第4次任务的第3次执行
第4次任务的第4次执行
4个任务是顺序执行的。
ScheduledThreadPool是一个固定大小的线程池,与FixedThreadPool相似,执行的任务是定时执行。
// 效果相似于Timer定时器 ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3); public ScheduledThreadPoolExecutor(int corePoolSize) { super(corePoolSize, //core pool size Integer.MAX_VALUE, //maximum pool size 0, //keep alive time TimeUnit.NANOSECONDS, new DelayedWorkQueue()); }
执行结果:
第1次任务的第1次执行
第2次任务的第1次执行
第3次任务的第1次执行
第2次任务的第2次执行
第1次任务的第2次执行
第3次任务的第2次执行
第2次任务的第3次执行
第1次任务的第3次执行
第3次任务的第3次执行
第2次任务的第4次执行
第1次任务的第4次执行
第3次任务的第4次执行
第4次任务的第1次执行
第4次任务的第2次执行
第4次任务的第3次执行
第4次任务的第4次执行
——与FixedThreadPool的区别?