0.线程池的好处
复用线程,减少线程创建和销毁的开销。
对线程的进行管理:定时,并发数的控制。
1.常用的三个线程池创建方式
Executors.newSingleThreadExecutor() 核心线程一个、最大线程一个、创建后不销毁、无限队列
1 /**
2 * new SingleThreadExecutor 核心线程一个、最大线程一个、创建后不销毁、无限队列
3 */
4 private static void singleThreadPool() {
5 ExecutorService executor = Executors.newSingleThreadExecutor();
6 for (int i = 0; i < 10; i++) {
7 executor.execute(new MyRunable(i));
8 }
9 // 执行完后销毁线程池
10 executor.shutdown();
11 }

Executors.newFixedThreadPool(nThreads) 指定核心线程数,核心线程和最大线程一样,创建后不销毁、无限队列
1 /**
2 * new FixedThreadPool 核心线程和最大线程一样,创建后不销毁、无限队列
3 */
4 private static void fixedThreadPool() {
5 int threadSize = 5;
6 ExecutorService executor = Executors.newFixedThreadPool(threadSize);
7 for (int i = 0; i < 15; i++) {
8 executor.execute(new MyRunable(i));
9 }
10 // 执行完后销毁线程池
11 executor.shutdown();
12 }

Executors.newCachedThreadPool() 核心线程零个、最大线程无限、创建后 60s 无复用销毁、同步队列
1 /**
2 * new CachedThreadPool 核心线程零个、最大线程无限、创建后60s无复用销毁、同步队列
3 */
4 private static void cachedThreadPool() {
5 ExecutorService executor = Executors.newCachedThreadPool();
6 for (int i = 0; i < 100; i++) {
7 executor.execute(new MyRunable(i));
8 }
9 // 执行完后销毁线程池
10 executor.shutdown();
11 }

2.个人理解
2.1日常使用三种已经可以满足使用, 关键是看个人对线程池的理解,
2.2 在线程池中,先创建核心线程,多出来的任务先放到队列中,直到队列存放不下才会创建新的线程,直到最大线程数,超过最大线程数将会抛出拒绝异常。
2.3 为什么任务自己或父类需要实现过 Runnable 接口?核心原理,任务实现了Runnable接口,重写 run() 方法 实际上执行的时候不是把任务当作线程执行,而是 任务对象.run() 方法来执行任务的。
2.4 线程池如何做到线程复用?实际上线程池中执行任务,获取队列中的任务,然后调用任务中的 run() 方法而已,当队列中没有任务的时候,就进行阻塞,不断获取任务。