Java--JUC--ThreadPool(线程池)
- 例子:ThreadPoolDemo,避免new 连接
- 为什么要用线程池
-
- 如何使用线程池
-
Arrays.copyOf(); 数组的工具类 Collections.synchronizedList(); 集合的工具类 ExecutorService threadPool= Executors.newFixedThreadPool(5); //一池五个受理线程,类似于银行有五个受理窗口
- 架构说明
-
- 编码实现
-
// 执行长期任务性能好,创建一个线程池,一池有n个固定的线程,有固定的线程数的线程池 ExecutorService executorService=Executors.newFixedThreadPool(5);
-
// 一个一个任务的执行,一池一线程,类似于1个受理窗口 ExecutorService executorService1=Executors.newSingleThreadExecutor();
-
// 一池n线程,类似于银行有n个受理窗口,自动扩容 ExecutorService executorService2=Executors.newCachedThreadPool();
-
- ThreadPool底层原理(ThreadPoolExecutor)
-
-
- 线程池的几个重要的参数
-
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException(); if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException(); this.acc = System.getSecurityManager() == null ? null : AccessController.getContext(); this.corePoolSize = corePoolSize; this.maximumPoolSize = maximumPoolSize; this.workQueue = workQueue; this.keepAliveTime = unit.toNanos(keepAliveTime); this.threadFactory = threadFactory; this.handler = handler; }
-
corePoolSize: 线程池中的常驻核心线程数
-
maximumPoolSize: 线程池中能够容纳同时
执行的最大线程数,此值必须大于等于1 -
keepAliveTime: 多余的空闲线程的存活时间
当前池中线程数量超过corePoolSize时,当空闲时间
达到keepAliveTime时,多余线程会被销毁直到
只剩下corePoolSize'个线程为止 -
unit: keepAliveTime的单位
-
workQueue: 任务队列,被提交但尚未被执行的任务
-
threadFactory: 表示生成线程池中工作线程的线程工厂,
用于创建线程,- -般默认的即可 -
handler: 拒绝策略,表示当队列满了,并且工作线程大于
等于线程池的最大线程数(maximumPoolSize) 时如何来拒绝
请求执行的runnable的策略
-
- 线程池底层工作原理(线程池只是控制运行的线程数量)
- corePoolSize=今日当值窗口
- maximumPoolSize=扩容窗口(扩容的窗口包括今日当值窗口)
- blocking Queue=候客区
-
- 线程池有哪个?生产中如何设置合理的参数
-
线程池的拒绝策略
- 是什么
-
-
JDK内置的拒绝策略
-
AbortPolicy(默认):直接抛出RejectedExecutionException异常阻止 系统正常运行
-
CallerRunsPolicy:“调用者运行”一种调节机制,该策略既不会抛弃任务,也不会抛出异常,而是将某些任务回退到调用者,从而降低新任务的流量。
-
DiscardOldestPolicy:抛弃队列中等待最久的任务,然后把当前任务加人队列中尝试再次提交当前任务。
-
DiscardPolicy:该策略默默地丢弃无法处理的任务,不予任何处理也不抛出异常。如果允许任务丢失,这是最好的一-种策略。
-
-
以上内置拒绝策略均实现了RejectedExecutionHandle接口
- 是什么
-
在工作中单一的/固定数的/可变的三种创建线程池的方法哪个用的多?超级大坑
-
答案是一个都不用,我们在工作中只能使用自定义的
- Executor中JDK给你提供了,为什么不用
-
OOM : java内存溢出
-
空指针异常,类型转换异常
-
-
-
在工作中如何使用线程池,是否自定义过线程池:
- 代码
-
package com.model.threadpool; import java.util.concurrent.*; /** * @Description:测试类 * @Author: 张紫韩 * @Crete 2021/6/8 17:12 */ public class ThreadPoolDemo { public static void main(String[] args) { System.out.println(Runtime.getRuntime().availableProcessors()); //内核cpu的数量 ExecutorService threadPool = new ThreadPoolExecutor( 2, //线程核心数 5, //线程最大数 (最大的线程数量=内核数量+1) 3L, //保留时间 TimeUnit.SECONDS, //保留时间的单位 new LinkedBlockingQueue<>(3), //阻塞队列(候车区) Executors.defaultThreadFactory(), //线程工程默认值 new ThreadPoolExecutor.AbortPolicy()); //1.拒绝策略,默认(抛出异常) // new ThreadPoolExecutor.CallerRunsPolicy()); //2.拒绝策略(会退给请求者) // new ThreadPoolExecutor.DiscardPolicy()); //3.拒绝策略(允许任务丢失,抛弃无法执行的任务) // new ThreadPoolExecutor.DiscardPolicy()); //4.拒绝策略(允许任务丢失,抛弃执行来的最晚的无法处理的任务) //最大的线程数容量是: 线程最大数+阻塞队列数 /** * 模拟十人来银行办理业务,目前池子中只有5名工作人员 * */ try { for (int i = 0; i < 9 ; i++) { final int t=i; threadPool.execute(()->{ System.out.println(Thread.currentThread().getName()+"处理业务\t"+t+"办理业务"); }); } }catch (Exception e){ e.printStackTrace(); }finally { threadPool.shutdown(); } } }
-