【线程池】如何判断线程池中的任务执行完毕(三)

news2024/9/19 21:36:57

                                               

目录

                                               

前言

1. isTerminated()方法

2. awaitTermination()方法

3.getTaskCount()方法和executor.getCompletedTaskCount()方法结合使用

4.使用CountDownlatch类


                                                前言

         通常我们使用线程池的时候,系统处于运行的状态,而线程池本身就是主要为了线程复用,需要线程池跟随系统一直跑起来。

        大多数时候,对于我们来说线程池就是一个黑盒,纵然我们可能对线程池的实现,底层原理盘的比老核桃还圆润,但是对于线程池的异常处理、事务处理、上下文传递、以及如何判断线程池中的任务执行状态,我们仍然是不可言状的。无法掌控、无法预测,会在一些细微时候给我们的应用程序带来致命一击。

        那么我来聊下以下几种判断线程池中任务是否执行完毕的方式,谁赞成,谁反对。


          

        我们先把线程池启动起来,线程数5个,往线程池中提交10个任务。

        

        基于上面的线程池,开始表演


        1. isTerminated()方法

        通过终止线程池 判断线程池中是否终止 来判断任务是否执行完毕 但是一般线程池也不会终止,不推荐使用。

        但是,有些个别情况我们确实需要停止线程池,比如系统停止的时候,异常终止的时候,如何优雅的停止线程池不得不来考虑下,在高负荷的系统中,停止线程池好似那狂奔180迈的迈巴赫踩下刹车,能安全平稳的停下来最好不过了。

        //终止线程池
        executor.shutdown();
        while (!executor.isTerminated()) {
            try {
                TimeUnit.MILLISECONDS.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("线程还在执行中");
            long taskCount = executor.getCompletedTaskCount();
            System.out.println("完成的任务数:" + taskCount);
        }

        执行结果如下,完成任务数10

        2. awaitTermination()方法

        使用awaitTermination()方法会阻塞当前线程,等待线程池执行任务,但是呢这个等待的时间是不确定,好似等待约会的女孩化妆,耗时不固定,但等待时间要足够长,缺点就是不可控,不可预测,正如我们的人生一样,茫茫无边际。

        如果等待时间足够长,输出是没问题的

        try {
            executor.awaitTermination(10, TimeUnit.SECONDS);
            long taskCount = executor.getCompletedTaskCount();
            System.out.println("完成的任务数:" + taskCount);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

          

        但如果恰好配置的时间不够,我们给配置成1s,就像恋爱时追女孩子的耐心不够,不好意思,你等不完她的化妆时间,注定孤独一生,自然也完成不了所有的任务

         可以看到我们在获取任务完成个数的时候只有5条。    

3. getTaskCount()方法和executor.getCompletedTaskCount()方法结合使用

while (executor.getTaskCount() != executor.getCompletedTaskCount()) {
            System.out.println("所有任务数:" + executor.getTaskCount() + ";已完成任务数" + executor.getCompletedTaskCount());
        }

        System.out.println("最后已完成的任务数:" + executor.getCompletedTaskCount());


4. 使用CountDownlatch类

        很多时候线程池并不专一,喜欢脚踏多个业务船,可能提交多种业务数据,我们只想看到我们提交的业务数据执行情况。    

        比如下面,我们再提交15条任务给线程池,线程池这家伙可是来着不拒的。

//在业务线程池正在执行上面10条任务的时候,再新提交15条任务,而我们只关注这15条任务该怎么做呢
        for (int i = 0; i < 15; i++) {
            int finalI = i;
            executor.execute(() -> {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

                System.out.println("【新提交的任务】" + Thread.currentThread().getName() + " 执行完了第" + finalI + "个任务") ;
            });

        }

        这个时候我们就可以请求外援,使用CountDownlatch来进行上述代码的改造,通过countDown()方法进行计数,await()方法阻塞等待,对完成的任务进行判断。 

        CountDownLatch latch = new CountDownLatch(15);
        for (int i = 0; i < 15; i++) {
            int finalI = i;
            executor.execute(() -> {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("【新提交的任务】" + Thread.currentThread().getName() + " 执行完了第" + finalI + "个任务") ;
                latch.countDown();
            });
        }
        latch.await();
        System.out.println("新提交的任务执行完成啦");
        System.out.println("最后已完成的总计任务数:" + executor.getCompletedTaskCount());

5. 手动维护一个线程安全的计数器

        比如说JUC包下常见的基于CAS的AtomicInteger类,基于底层的unsafe类,在多线程的情况下依然可以保证线程的安全,我们可以放心的将它在线程池中进行累加,直到累加到和提交的任务数量一致,线程池也就执行完了所有的任务。

6. 使用Future

        我们也可以换个路子,提交线程池不适用execute()方法,使用submit()方法,记得使用submit()方法要谨慎些,具体的坑可以参考之前的文章【线程池】换个姿势来看线程池中不一样的阻塞队列(一)_走了一些弯路的博客-CSDN博客

       

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/960119.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CVE-2023-23752:Joomla未授权访问漏洞复现

CVE-2023-23752&#xff1a;Joomla未授权访问漏洞复现 前言 本次测试仅供学习使用&#xff0c;如若非法他用&#xff0c;与本文作者无关&#xff0c;需自行负责&#xff01;&#xff01;&#xff01; 一.Openfire简介 Joomla是一个免费的开源内容管理系统&#xff08;CMS&a…

Java for循环每次都通过list.size()和 string.length()获取大小性能

有人说在for循环之前用一个局部变量先获取到list.size()、str.length()&#xff0c;然后在for循环的判断条件里通过这个局部变量替换list.size()、str.length()会节省数据计算的时间。事实真的是这样吗&#xff1f;下面就为大家解答这个问题。 说明&#xff1a;此文章针对Andro…

打造成功的砍价营销大解析,销量飙升

砍价活动是吸引顾客的一种有效方式&#xff0c;可以帮助提高销量和提升品牌知名度。在乔拓云平台上&#xff0c;我们提供了一套简单易用的工具&#xff0c;让您能够轻松地制作一个成功的砍价活动。下面&#xff0c;我将详细介绍具体步骤&#xff0c;让您能够轻松上手。 第一步&…

港联证券|4%!央行宣布:降准!新股大涨138%,再现触发临停!

煤炭领涨两市&#xff0c;多股有望继续高份额分红。 沪指早间冲高后有所回落&#xff0c;上证50盘中一度涨超1%&#xff0c;保险、银行等大金融板块拉升。食品、乳业、白酒、零售等大消费板块全线拉升&#xff0c;半导体芯片股走低&#xff0c;泰凌微跌超10%&#xff0c;寒武纪…

8个神奇的UI设计工具,小白也可轻松上手

随着设计工作的不断发展&#xff0c;市面上好用的设计工具也丰富起来&#xff0c;今天本文共整理了8个好用的设计工具&#xff0c;可以充分满足设计师对设计工具使用的需求&#xff0c;接下来就一起来看看吧&#xff01; 1、即时设计 即时设计是一个面向个人设计师和中小型设…

考前冲刺上岸浙工商MBA的备考经验分享

2023年对于许多人来说都是不平凡的一年&#xff0c;历经三年的抗争&#xff0c;我们终于成功结束了疫情。而我也很幸运的被浙工商MBA项目录取&#xff0c;即将开始全新的学习生活。身为一名已在职工作6年的人&#xff0c;能够重回校园真是一种特别令人激动的体验。今天&#xf…

极致内卷的中国电商路在何方?

2023年上半年最大的价值在于终于找到了确定性&#xff1a;1&#xff0c;消费仍然在增长是确定的&#xff0c;只是增速不再那么高&#xff1b;2&#xff0c;必须从“流量”转向做“留量”是确定的&#xff0c;无论是互联网还是传统消费领域&#xff0c;所有企业都在强调做单客运…

游戏发行商能够提供什么服务?

游戏发行商可以为游戏开发者提供广泛的服务&#xff0c;以帮助他们将游戏成功地引入市场并取得更好的业绩。以下是游戏发行商可能提供的一些服务&#xff1a; 市场营销和宣传&#xff1a;发行商通常具有丰富的市场营销经验&#xff0c;可以制定并执行有效的宣传和营销策略。他们…

硬盘数据恢复- 硬盘中文件打开报错的数据恢复案例

硬盘数据恢复环境&故障情况&#xff1a; 某单位重要数据在一台WINDOWS操作系统的PC机上通过网络共享给公司员工使用。这台PC同时也连接着打印机提供打印服务&#xff0c;很多员工直接将文件拷贝到这台PC上进行打印。该PC机上只有一块500G磁盘。 该PC的F盘分区所有类型文件突…

Effetive STL | 条款2 : 小心对“容器无关代码”的幻想

Effetive STL | 条款2 &#xff1a; 小心对“容器无关代码”的幻想 文章目录 Effetive STL | 条款2 &#xff1a; 小心对“容器无关代码”的幻想STL 容器特点推行自己的容器容器能力的交集 封装Method1: typedefMethod2: class>>>>> 欢迎关注公众号【三戒纪元】…

大数据学习:kafka-producer源码分析

kafka-producer源码分析 kafka-1.0.1源码下载地址 一.kafka发送示例 /*** Created by XiChuan on 2021/6/7.*/ public class ProducerTest {public static void main(String[] args) throws Exception {KafkaProducer<String, String> producer createProducer();JSO…

企业为什么需要IM “定制化”?

企业内外部的信息交流作为一种刚需&#xff0c;证明了企业级 IM 市场稳定可靠且前景十足的商业价值。不过&#xff0c;标准化的企业 IM 产品由于定制化能力不足&#xff0c;容易形成封闭的产品生态&#xff0c;对于企业管理者的吸引力正逐渐减弱。 WorkPlus作为一个企业数字化…

电子科大软件系统架构设计——系统分析与设计概述(含课堂作业、练习答案)

系统分析与设计概述 信息系统概述 what 信息系统是一种能够完成对业务数据进行采集、转换、加工、计算、分析、传输、维护等信息处理&#xff0c;并能就某个方面问题给用户提供信息服务的计算机应用系统。 组成 信息化基础设施&#xff08;计算机、计算机网络、服务器、系统…

git文件夹内容详解

.git文件夹是Git版本控制系统在项目根目录下创建的隐藏文件夹&#xff0c;包含了Git仓库的所有相关信息。如下是.git文件夹中常见的一些内容及其作用&#xff1a; HEAD&#xff1a;指向当前所在的分支&#xff08;或者是一个特定的提交&#xff09;。 branches&#xff1a;存储…

SoftwareTest1 - 打破你对软件测试的偏见

软件测试答疑篇 一 . 什么是软件测试二 . 软件测试和软件开发的区别2.1 难易程度2.2 工作环境2.3 薪水("钱"景)2.4 繁忙程度2.5 测试和研发中调试的区别 三 . 软件测试岗位四 . 软件测试人员应该具备的素质4.1 综合能力4.2 优秀的测试用例设计能力4.3 掌握自动化测试…

ShardingSphere——柔性事务SEATA原理

摘要 Apache ShardingSphere集成了 SEATA 作为柔性事务的使用方案&#xff0c;本文主要介绍其实现ShardingSphere中柔性事务SEATA原理原理。帮助你更好的理解ShardingSphere原理。同时帮助大家更好的使用柔性事务SEATA原理。 一、Seata柔性事务 Apache ShardingSphere 集成了…

合并区间【贪心算法】

合并区间 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间&#xff0c;并返回 一个不重叠的区间数组&#xff0c;该数组需恰好覆盖输入中的所有区间 。 class Solution {public int[][] merge(int[…

uniapp 配置并使用 VueX

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化。 uni-app 内置了 VueX 1、创建需要的文件 右键点击 根目录【我的是 uni-shop】&#xff0c;然后新建 目录&a…

ICCV 2023 | 利用双重聚合的Transformer进行图像超分辨率

导读 本文提出一种同时利用图像空间和通道特征的 Transformer 模型&#xff0c;DAT&#xff08;Dual Aggregation Transformer&#xff09;&#xff0c;用于图像超分辨&#xff08;Super-Resolution&#xff0c;SR&#xff09;任务。DAT 以块间和块内的双重方式&#xff0c;在空…

轻松管理不同类型的文件,高效将文件按类型进行移动归类

如果你经常需要处理不同类型的文件素材&#xff0c;例如图片、音频、视频等&#xff0c;那么你一定知道这是一项繁琐的任务。为了帮助你快速整理这些文件&#xff0c;我们推出了一款强大的文件管理工具&#xff0c;让你能够轻松地将不同类型的文件素材归类到不同文件夹里单独保…