第11章 线程池
作者:互联网
11.1 线程池简介
线程池(英语: thread pool) : 一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利用,还能防止过分调度。
例子: 10年前单核CPU电脑,假的多线程,像马戏团小丑玩多个球, CPU需要来回切换。现在是多核电脑 ,多个线程各自跑在独立的CPU上,不用切换效率高。
线程池的优势:线程池做的工作只要是控制运行的线程数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量, 超出数量的线程排队等候,等其他线程执行完毕,再从队列中取出任务来执行。
它的主要特点为:
● 降低资源消耗: 通过重复利用已创建的线程降低线程创建和销毁造成的销耗。
● 提高响应速度: 当任务到达时,任务可以不需要等待线程创建就能立即执行。
● 提高线程的可管理性: 线程是稀缺资源,如果无限制的创建,不仅会销耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。.
● Java 中的线程池是通过Executor框架实现的,该框架中用到了Executor , Executors,ExecutorService , ThreadPoolExecutor这几个类
UML类图:
package JUC.pool; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; //演示线程池三种常用分类 public class ThreadPoolDemo1 { public static void main(String[] args) { //一池五线程 //5个窗口 ExecutorService threadPool1 = Executors.newFixedThreadPool(5); //一池一线程 //1个窗口 ExecutorService threadPool2 = Executors.newSingleThreadExecutor(); //一池可扩容线程 ExecutorService threadPool3 = Executors.newCachedThreadPool(); //10个顾客请求 try { for (int i = 1; i <= 20; i++) { //执行 threadPool3.execute(() -> { System.out.println(Thread.currentThread().getName()+" 办理业务"); }); } } catch (Exception e) { e.printStackTrace(); } finally { //关闭 threadPool3.shutdown(); } } }
11.2 线程池七个参数介绍
11.3 线程池工作流程和拒绝策略
工作流程如上图:拿银行窗口服务客户来说,常驻线程数为2,相当于常开两个窗口,最大线程数为5,相当于最多有5个窗口,阻塞队列为3,相当于等待区最多有3个位置。当窗口1、2在服务客户时,等待区坐满了客户3、4、5,这个时候来了客户6、7、8,大堂经理会单独对他们进行服务,相当于创建了线程6、7、8(等价开启窗口6、7、8),这个时候已经达到最大线程数,如果再来了客户9,那么会进行拒绝策略,拒绝策略参考下图:
AbortPolicy:银行服务不了的客户,让客户去其他银行处理。(客户9)
CallerRunsPolicy:谁让客户来银行的,就让客户去找谁。(客户9)
DiscardOldestPolicy:让银行等待区等最久的客户离开。(客户5离开,客户9进来)
DiscardPolicy:不理客户。(客户9)
11.4 自定义线程池
package JUC.pool; import java.util.concurrent.*; //自定义线程池创建 public class ThreadPoolDemo2 { public static void main(String[] args) { ThreadPoolExecutor threadPool = new ThreadPoolExecutor( 2, 5, 2L, TimeUnit.SECONDS, new ArrayBlockingQueue<>(3), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); //10个顾客请求 try { for (int i = 1; i <= 10; i++) { //执行 threadPool.execute(() -> { System.out.println(Thread.currentThread().getName()+" 办理业务"); }); } } catch (Exception e) { e.printStackTrace(); } finally { //关闭 threadPool.shutdown(); } } }
标签:11,窗口,Executors,创建,客户,线程,ExecutorService 来源: https://www.cnblogs.com/RobertYu666/p/16219822.html