Java线程池

线程池

什么是线程池

一句话,线程的集合

线程池的好处

(摘录:https://blog.csdn.net/qq_40093255/article/details/116990431)

1.降低系统资源消耗,通过重用已存在的线程,降低线程创建和销毁造成的消耗;
2.提高系统响应速度,当有任务到达时,无需等待新线程的创建便能立即执行;
3.方便线程并发数的管控,线程若是无限制的创建,不仅会额外消耗大量系统资源,更是占用过多资源而阻塞系统或oom等状况,从而降低系统的稳定性。线程池能有效管控线程,统一分配、调优,提供资源使用率;
4.更强大的功能,线程池提供了定时、定期以及可控线程数等功能的线程池,使用方便简单。

线程池的创建

1.通过Executors创建

2.通过ThreadPoolExecutor 创建

具体有7种实现方法:

  1. Executors.newFixedThreadPool:创建一个固定大小的线程池,可控制并发的线程数,超出的线程会在队列中等待。

            Thread thread = new Thread(() -> System.out.println("线程" + Thread.currentThread().getName() + "执行"));
            //两种执行方式
            threadPool.submit(thread);
            threadPool.execute(thread);
    
  2. Executors.newCachedThreadPool:创建一个可缓存的线程池,若线程数超过处理所需,缓存一段时间后会回收,若线程数不够,则新建线程。

            ExecutorService threadPool = Executors.newCachedThreadPool();
            for (int i = 0; i < 10; i++) {
                int finalI = i;
                threadPool.execute(() -> {
                    System.out.println("(" + finalI + ")线程执行:" + Thread.currentThread().getName());
                });
            }
    
  3. Executors.newSingleThreadExecutor:创建单个线程数的线程池,它可以保证先进先出的执行顺序。

            //可以保证顺序执行
            ExecutorService threadPool = Executors.newSingleThreadExecutor();
            for (int i = 0; i < 10; i++) {
                int finalI = i;
                threadPool.execute(() -> {
                    System.out.println(finalI + ":" + Thread.currentThread().getName() + "执行任务");
                });
    
            }
    
  4. Executors.newScheduledThreadPool:创建一个可以执行延迟任务的线程池。

            ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(4);
            System.out.println("任务启动时间:" + LocalDateTime.now());
            //任务会延迟一秒执行
            threadPool.schedule(() -> {
                System.out.println("任务执行时间:" + LocalDateTime.now());
    
            }, 1, TimeUnit.SECONDS);
    
  5. Executors.newSingleThreadScheduledExecutor:创建一个单线程的可以执行延迟任务的线程池。

            ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
            System.out.println("任务启动时间:" + LocalDateTime.now());
            scheduledExecutorService.schedule(() -> {
                System.out.println("任务执行时间:" + LocalDateTime.now());
            }, 1, TimeUnit.SECONDS);
    
  6. Executors.newWorkStealingPool:创建一个抢占式执行的线程池(任务执行顺序不确定)【JDK 1.8 添加】

            ExecutorService executorService = Executors.newWorkStealingPool();
            for (int i = 0; i < 10; i++) {
                int finalI = i;
                executorService.execute(()->{
                    System.out.println(finalI +"被执行,线程名:"+Thread.currentThread().getName());
                });
            }
            //确保任务执行完
            while (!executorService.isTerminated()){
    
            }
    
  7. ThreadPoolExecutor:手动创建线程池的方式,它创建时最多可以设置 7 个参数。

            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 100, TimeUnit.SECONDS, new LinkedBlockingDeque<>(10));
            // 执行任务
            for (int i = 0; i < 10; i++) {
                int finalI = i;
                threadPoolExecutor.execute(() -> {
                    System.out.println(finalI + " 被执行,线程名:" + Thread.currentThread().getName());
                });
            }
    

ThreadPoolExecutor 相比于其他创建线程池的优势在于,它可以通过参数来控制最大任务数和拒绝策略,让线程池的执行更加透明和可控

线程池参数

  • corePoolSize 核心线程数

    ​ 核心线程数会一直存在,即使没有任务执行,也会创建线程直到到达核心线程数

  • queueCapacity 任务队列容量

    没有闲置的核心线程时,会将任务加到任务队列中等待

  • maxPoolSize 最大线程数

    线程池中允许的最大线程数量

  • keepAliveTime 线程空余时间

    当线程空余时间达到设置的值,线程就会关闭,但不小于核心线程数

  • allowCoreThreadTimeout 允许核心线程超时

    当值为true时,核心线程超时也会关闭

  • rejectedExecutionHandler 任务拒绝处理器

    当线程数量到达最大线程数,且任务队列已满。执行拒绝策略

线程池默认的参数:

corePoolSize = 1
queueCapacity = Integer.MAX_VALUE
maxPoolSize = Integer.MAX_VALUE
keepAliveTime = 60秒
allowCoreThreadTimeout = false
rejectedExecutionHandler = AbortPolicy()

线程池的执行顺序

在这里插入图片描述
执行步骤:

1.创建线程池后

2.任务提交后,查看是否有核心线程

​ 3.1 没有 -> 就创建核心线程 -> 执行任务 -> 执行完毕后又回到线程池中

​ 3.2 有 -> 查看是否有闲置核心线程:

​ 4.1 有 -> 执行任务 -> 执行完毕后又回到线程池

​ 4.2 没有 -> 查看当前核心线程数是否核心线程数量:

​ 5.1 否 -> 就创建核心线程 -> 执行任务 -> 执行完毕后又回到线程池中

​ 5.2 是 -> 查看任务列表是否装载满:

​ 6.1 没有 -> 就放入列表中,等待出现闲置线程

​ 6.2 装满 -> 查看是否有普通线程(核心线程数到最大线程数量之间的线程)

​ 7.1 没有 -> 就创建普通线程 -> 执行任务 -> 执行完毕后又回到线程池中

​ 7.2 有 -> 查看是否有闲置普通线程

​ 7.1.1 有 -> 执行任务 -> 执行完毕后又回到线程池中

​ 7.1.2 没有 -> 查看现在所有线程数量是否为最大线程数:

​ 8.1 是 -> 执行处理方案(默认处理抛出异常)

​ 8.2 否 ->就创建普通线程-> 执行任务 -> 执行完毕后又回到线程池中
7.1.1 有 -> 执行任务 -> 执行完毕后又回到线程池中

​ 7.1.2 没有 -> 查看现在所有线程数量是否为最大线程数:

​ 8.1 是 -> 执行处理方案(默认处理抛出异常)

​ 8.2 否 ->就创建普通线程-> 执行任务 -> 执行完毕后又回到线程池中

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值