当前位置: 首页 > article >正文

【JUC】线程池

【JUC】线程池

文章目录

  • 【JUC】线程池
    • 1. 创建线程池
    • 2. 关闭线程池
    • 3. 拒绝策略
    • 4. 线程创建工厂
    • 5. Executors工具类
      • 5.1 创建单个线程的线程池
      • 5.2 创建多个线程的线程池

1. 创建线程池

线程池的构造方法:

public ThreadPoolExecutor(int corePoolSize,//核心线程池大小
                          int maximumPoolSize,//最大线程池大小
                          long keepAliveTime,//线程最大空闲时间
                          TimeUnit unit,//线程最大空闲时间的单位
                          BlockingQueue<Runnable> workQueue,//线程等待队列
                          ThreadFactory threadFactory,//线程创建工厂
                          RejectedExecutionHandler handler//拒绝策略
                         ) {}
  • corePoolSize:核心线程池大小,我们每向线程池提交一个多线程任务时,无论是否存在其他空闲线程,都会创建一个新的 核心线程 ,直到到达核心线程池大小为止,之后会尝试复用线程资源。当然也可以在一开始就全部初始化好,调用 prestartAllCoreThreads() 即可。
  • maximumPoolSize:最大线程池大小,当线程池中所有的线程都处于运行状态并且对待队列也满了,那么就会直接尝试创建新的 非核心线程 运行,但是总线程数不能超过最大线程池大小。
  • keepAliveTime:线程最大空闲时间,当 非核心线程 空闲超过一定时间,会自动销毁。
  • unit:线程最大空闲时间的时间单位
  • workQueue:线程等待队列,当线程池中 核心线程 已满时,就会将任务暂时存到等待队列中,直到有线程资源可用为止(核心线程和队列都满了,就会去尝试创建非核心线程)。
  • threadFactory:线程创建工厂,我们可以干涉线程池中线程的创建过程,进行自定义。
  • handler:拒绝策略,当等待队列和线程池都没有空间了,也不能再创建非核心线程了。此时来了一个新的多线程任务,那么只能拒绝了,这时就会根据当前设定的拒绝策略进行处理。

2. 关闭线程池

线程池.shutdownNow();//立马关闭线程池,取消所有等待中的任务以及试图中断正在执行的任务,关闭后无法再提交任务,一律拒绝。
线程池.shutdown();//执行完等待队列中的任务再关闭。

3. 拒绝策略

线程池的拒绝策略主要有以下四种:

  1. AbortPolicy(默认):直接抛异常。
  2. CallerRunsPolicy:直接让提交人物的线程执行这个任务,如主线程向线程池提交这个任务,那么就由主线程执行。
  3. DiscardOldestPolicy:丢弃队列中最近的一个任务,替换为当前任务。
  4. DiscardPolicy:什么也不做。

除了这四种策略外,我们也可以使用自定义的策略:

ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4,3, TimeUnit.SECONDS,new SynchronousQueue<>(),
        //自定义拒绝策略
        new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                System.out.println("自定义拒绝策略");
                r.run();
            }
        }
);

4. 线程创建工厂

ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 3, TimeUnit.SECONDS, new SynchronousQueue<>(),
        //自定义线程工厂
        new ThreadFactory() {
            int count = 0;

            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r, "线程" + (++count));
            }
        },
        //自定义拒绝策略
        new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                System.out.println("自定义拒绝策略");
                r.run();
            }
        }
);

线程池在执行任务的过程中如果抛出了异常,那么线程池就会销毁这个线程。


5. Executors工具类

5.1 创建单个线程的线程池

除了自己创建线程池这一方法,我们也可以使用 Executors 工具类来快速创建线程池:

//创建一个只有一个线程的线程池
private static final ExecutorService SECKILL_ORDER_EXECUTOR = Executors.newSingleThreadExecutor();

它的内部实现如下所示:

public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
                                0L, TimeUnit.MILLISECONDS,
                                new LinkedBlockingQueue<Runnable>()));
}

5.2 创建多个线程的线程池

private static final ExecutorService CACHE_REBUILD_EXECUTOR = Executors.newFixedThreadPool(10);

它的内部实现如下:

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

我们最终发现,该方法也是通过调用7个参数的线程池构造方法来创建的线程池。

它将核心线程数和最大线程数设置值相同,并且非核心线程的空闲时间设置为0,因为根本就没有非核心线程,全是核心线程,并且采用的是一个无界的LinkedBlockingQueue作为等待队列。


http://www.kler.cn/a/4037.html

相关文章:

  • 华为数据中心CE系列交换机级联M-LAG配置示例
  • Spring Boot 实战篇(四):实现用户登录与注册功能
  • 基于Java的百度AOI数据解析与转换的实现方法
  • 80_Redis内存策略
  • 主链和Layer2之间资产转移
  • “飞的”点外卖,科技新潮流来袭
  • WireShark如何抓包,各种协议(HTTP、ARP、ICMP)的过滤或分析,用WireShark实现TCP三次握手和四次挥手
  • 各种硬件对应”位数“,各种字长,编址方式的区分。
  • 常用脚本命令sort head tail grep awk sed uniq
  • 软文写作技巧有哪些?建议收藏
  • 基于Java+Springboot+vue的网上商城购物系统设计与实现【源码(完整源码请私聊)+论文+演示视频+包运行成功】
  • Linux中的管道符与grep命令
  • 【数据库】Mysql数据库的三大范式1NF 2NF 3NF
  • vue 高德地图添加多个点标记
  • 速度与兼容性功能大比拼:7款浏览器测评,哪一款更好用
  • 基于云计算的Java版云HIS系统源码,已在公立二甲医院应用三年
  • 云原生周刊:K8s 在 v1.27 中移除的特性和主要变更
  • 社区之声|Grant Program支持Moonbeam生态壮大
  • 物理机CPU使用率报警
  • 蓝桥杯每日一真题——[蓝桥杯 2021 省 AB2] 负载均衡(优先队列,模拟)
  • 自动指出测试问题,TestGPT来袭,测试工程师,你准备好了么
  • ShowMeAI周刊 | AI独立开发者:帆船旅行但月入万刀;创业吧!新黄金时代来了;资本看好哪些创业方向;被AI震麻的一周again
  • 线程基础知识总结
  • 18个基础命令教你轻松拿捏华为设备的各种状态!-HCIA HCIP
  • leetcode 搜索插入位置(35)
  • GPS时间序列分析---剔除跳跃点,拟合时间序列