ThreadPool线程池

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 }

 

ThreadPool线程池

 

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 }

ThreadPool线程池

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 }

ThreadPool线程池

 

2.个人理解

2.1日常使用三种已经可以满足使用, 关键是看个人对线程池的理解,

2.2 在线程池中,先创建核心线程,多出来的任务先放到队列中,直到队列存放不下才会创建新的线程,直到最大线程数,超过最大线程数将会抛出拒绝异常。

2.3 为什么任务自己或父类需要实现过 Runnable 接口?核心原理,任务实现了Runnable接口,重写 run() 方法 实际上执行的时候不是把任务当作线程执行,而是 任务对象.run() 方法来执行任务的。

2.4 线程池如何做到线程复用?实际上线程池中执行任务,获取队列中的任务,然后调用任务中的 run() 方法而已,当队列中没有任务的时候,就进行阻塞,不断获取任务。