Java多线程技术11——ThreadPoolExecutor类的使用2

1 isShutdown()方法

        public boolean  isShutdown()方法的作用是判断线程池是否已经关闭

public class Run1 {public static void main(String[] args) {Runnable runnable = new Runnable() {@Overridepublic void run() {try {System.out.println("开始: " + Thread.currentThread().getName());Thread.sleep(1000);System.out.println("结束: " + Thread.currentThread().getName());}catch (InterruptedException e){e.printStackTrace();}}};ThreadPoolExecutor pool = new ThreadPoolExecutor(2,2,Integer.MAX_VALUE, TimeUnit.SECONDS,new LinkedBlockingDeque<>());pool.execute(runnable);System.out.println("A = " + pool.isShutdown());pool.shutdown();System.out.println("B = " + pool.isShutdown());}
}

        由运行结果可知,只要调用了shutdown()方法,isShutdown()方法的返回值就是true。

2  isTerminating()和isTerminated()方法

        public boolean isTerminating()方法:如果此执行程序处于在shutdown或shutdownNow之后且正在终止但尚未完全终止的过程中,也就是还有任务在执行,则返回true。此方法可以比喻成门是否正在关闭。

      public boolean isTerminated()方法:如果关闭后所有任务都已完成,则返回true。此方法可以比喻成门是否已经关闭。

        shutdown或shutdownNow方法的功能是发出一个关闭线程池的命令,isShutdown方法用于判断关闭线程池的命令发出或未发出。  isTerminating方法用于判断线程池是否正在关闭中,isTerminated方法判断线程池是否已经关闭了。

public class MyRunnable implements Runnable{@Overridepublic void run() {try {System.out.println(Thread.currentThread().getName()+"begin: "+ Utils.data(System.currentTimeMillis()));Thread.sleep(2000);System.out.println(Thread.currentThread().getName()+"end: "+ Utils.data(System.currentTimeMillis()));}catch (InterruptedException e){e.printStackTrace();}}
}

public class Test {public static void main(String[] args) throws InterruptedException {MyRunnable runnable = new MyRunnable();ThreadPoolExecutor pool = new ThreadPoolExecutor(2,99999,99999, TimeUnit.SECONDS,new LinkedBlockingDeque<>());pool.execute(runnable);pool.execute(runnable);pool.execute(runnable);pool.execute(runnable);System.out.println(pool.isTerminating() + " " + pool.isTerminated());pool.shutdown();Thread.sleep(1000);System.out.println(pool.isTerminating() + " " + pool.isTerminated());Thread.sleep(1000);System.out.println(pool.isTerminating() + " " + pool.isTerminated());Thread.sleep(1000);System.out.println(pool.isTerminating() + " " + pool.isTerminated());Thread.sleep(1000);System.out.println(pool.isTerminating() + " " + pool.isTerminated());Thread.sleep(1000);System.out.println(pool.isTerminating() + " " + pool.isTerminated());}
}

3  awaitTermination(long timeout, TimeUnit unit)

         public boolean awaitTermination(long timeout, TimeUnit unit)方法:查看在指定的时间内,线程池是否已经终止工作,也就是“最多”等待多少时间后去判断线程池是否已经终止工作。如果在指定的时间之内,线程池销毁会导致该方法不再阻塞,而超过timeout时间也会导致该方法不再阻塞。此方法的使用需要shutdown()方法的配合。

public class MyRunnable1 implements Runnable{@Overridepublic void run() {try {System.out.println(Thread.currentThread().getName() + " " + Utils.data(System.currentTimeMillis()));Thread.sleep(4000);System.out.println(Thread.currentThread().getName() + " " + Utils.data(System.currentTimeMillis()));}catch (InterruptedException e){e.printStackTrace();}}
}
public class Test1 {public static void main(String[] args) throws InterruptedException {MyRunnable1 runnable1 = new MyRunnable1();ThreadPoolExecutor pool = new ThreadPoolExecutor(2,99999,9999L, TimeUnit.SECONDS,new LinkedBlockingQueue<>());pool.execute(runnable1);System.out.println("main开始:" + Utils.data(System.currentTimeMillis()));System.out.println(pool.awaitTermination(10,TimeUnit.SECONDS));System.out.println("main结束:" + Utils.data(System.currentTimeMillis()));}
}

        从控制台可以看出,main开始到main结束需要10秒,因为main线程并未销毁,所以 awaitTermination方法需要阻塞10秒。打印false的原因是未对线程池执行shutdown方法。如果对线程池执行shutdown方法,在运行时间上会有什么效果呢?

public class Test2 {public static void main(String[] args) throws InterruptedException {MyRunnable1 runnable1 = new MyRunnable1();ThreadPoolExecutor pool = new ThreadPoolExecutor(2,99999,9999L, TimeUnit.SECONDS,new LinkedBlockingQueue<>());pool.execute(runnable1);pool.shutdown();System.out.println("main开始:" + Utils.data(System.currentTimeMillis()));System.out.println(pool.awaitTermination(10,TimeUnit.SECONDS));System.out.println("main结束:" + Utils.data(System.currentTimeMillis()));}
}

        可以看出,main开始和mian结束之间耗时4秒,因为4秒后线程池销毁了,导致 awaitTermination方法取消阻塞。

4 set/getRejectedExceptionHandler()方法

        public void setRejectedExecutionHandler(RejectedExecutionHandler handler)和

        public RejectedExecutionHandler getRejectedExecutionHandler()方法的作用是可以处理任务被拒绝执行时的行为。

public class MyRunnable1 implements Runnable{private String username;public MyRunnable1(String username) {this.username = username;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}@Overridepublic void run() {try {System.out.println(Thread.currentThread().getName()+ "开始时间 =  " + Utils.data(System.currentTimeMillis()));Thread.sleep(4000);System.out.println(Thread.currentThread().getName()+ "结束时间 =  " + Utils.data(System.currentTimeMillis()));}catch (InterruptedException e){e.printStackTrace();}}
}
public class Run1 {public static void main(String[] args) {MyRunnable1 myRunnable1 = new MyRunnable1("a1");MyRunnable1 myRunnable2 = new MyRunnable1("a2");MyRunnable1 myRunnable3 = new MyRunnable1("a3");MyRunnable1 myRunnable4 = new MyRunnable1("a4");ThreadPoolExecutor pool = new ThreadPoolExecutor(2,3,999L, TimeUnit.SECONDS,new SynchronousQueue<>());pool.execute(myRunnable1);pool.execute(myRunnable2);pool.execute(myRunnable3);pool.execute(myRunnable4);}
}

        控制台打印的信息说明  MyRunnable1 myRunnable4 = new MyRunnable1("a4");任务被拒绝执行,在出现这样的异常时可以自定义拒绝执行任务的行为。创建MyRejectedExecutionHandler.java类。

public class MyRejectedExecutionHandler implements RejectedExecutionHandler {@Overridepublic void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {System.out.println(((MyRunnable1) r).getUsername() + "被拒绝执行");}
}

public class Run2 {public static void main(String[] args) {MyRunnable1 myRunnable1 = new MyRunnable1("a1");MyRunnable1 myRunnable2 = new MyRunnable1("a2");MyRunnable1 myRunnable3 = new MyRunnable1("a3");MyRunnable1 myRunnable4 = new MyRunnable1("a4");ThreadPoolExecutor pool = new ThreadPoolExecutor(2,3,999L, TimeUnit.SECONDS,new SynchronousQueue<>());pool.setRejectedExecutionHandler(new MyRejectedExecutionHandler());pool.execute(myRunnable1);pool.execute(myRunnable2);pool.execute(myRunnable3);pool.execute(myRunnable4);pool.shutdown();}
}

5 allowsCoreThreadTimeOut()和allowCoreThreadTimeOut(bool)方法

        allowsCoreThreadTimeOut(true)可使核心池中的空闲线程具有超时销毁的特性。其中,public boolean allowsCoreThreadTimeOut() 方法的作用是判断是否具有这个特性。

public void allowCoreThreadTimeOut(boolean value)方法的作用是设置是否有这个特性。

public class MyRunnable implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread() + "开始:" + Utils.data(System.currentTimeMillis()));System.out.println(Thread.currentThread() + "结束:" + Utils.data(System.currentTimeMillis()));}
}
public class Run1 {public static void main(String[] args) throws InterruptedException {ThreadPoolExecutor pool = new ThreadPoolExecutor(4,5,5, TimeUnit.SECONDS,new SynchronousQueue<>());System.out.println(pool.allowsCoreThreadTimeOut());for (int i = 0; i < 4; i++) {MyRunnable myRunnable = new MyRunnable();pool.execute(myRunnable);}Thread.sleep(8000);System.out.println(pool.getPoolSize());}
}

创建Run2.java类

public class Run2 {public static void main(String[] args) throws InterruptedException {ThreadPoolExecutor pool = new ThreadPoolExecutor(4,5,5, TimeUnit.SECONDS,new SynchronousQueue<>());pool.allowCoreThreadTimeOut(true);System.out.println(pool.allowsCoreThreadTimeOut());for (int i = 0; i < 4; i++) {MyRunnable myRunnable = new MyRunnable();pool.execute(myRunnable);}Thread.sleep(8000);System.out.println(pool.getPoolSize());}
}

 

6 prestartCoreThread()和prestartAllCoreThreads()方法

        在实例化ThreadPoolExecutor类后,线程池并没有核心线程,除非执行execute()方法,但是在不执行execute()方法时也可以通过执行prestartCoreThread()和prestartAllCoreThreads()方法来创建核心线程。

        public boolean prestartCoreThread()方法的作用是每调用一次就创建一个核心线程并使它变成启动状态,返回值类型为boolean,代表是否创建成功。

        public int prestartAllCoreThreads()方法的作用是同时启动全部核心线程,返回值是启动核心线程的数量。

public class Run1 {public static void main(String[] args) {ThreadPoolExecutor pools = new ThreadPoolExecutor(4,8,5, TimeUnit.SECONDS,new LinkedBlockingQueue<>());System.out.println("线程池中的线程数a= " + pools.getPoolSize());System.out.println("Z1 = " + pools.prestartCoreThread());System.out.println("线程池中的线程数a= " + pools.getPoolSize());System.out.println("Z2 = " + pools.prestartCoreThread());System.out.println("线程池中的线程数a= " + pools.getPoolSize());System.out.println("Z3 = " + pools.prestartCoreThread());System.out.println("线程池中的线程数a= " + pools.getPoolSize());System.out.println("Z4 = " + pools.prestartCoreThread());System.out.println("线程池中的线程数a= " + pools.getPoolSize());System.out.println("Z5 = " + pools.prestartCoreThread());System.out.println("线程池中的线程数a= " + pools.getPoolSize());System.out.println("Z6 = " + pools.prestartCoreThread());}
}

                

        最后连续打印了2个false代表核心池中的线程数量已经到了最大值,是4。不能再创建新的核心池中的线程了。

        创建Run2.java类。

public class Run2 {public static void main(String[] args) {ThreadPoolExecutor pools = new ThreadPoolExecutor(4,8,5, TimeUnit.SECONDS,new LinkedBlockingQueue<>());System.out.println("线程池中的线程数a= " + pools.getPoolSize());System.out.println("Z1 = " + pools.prestartAllCoreThreads());System.out.println("线程池中的线程数a= " + pools.getPoolSize());System.out.println();System.out.println("Z2 = " + pools.prestartAllCoreThreads());System.out.println("线程池中的线程数a= " + pools.getPoolSize());}
}

 

        打印信息Z2 = 0,说明核心池中的线程已满,不需要创建新的核心池中的线程。 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何信任机器学习模型的预测结果?

在本篇中&#xff0c;我将通过一个例子演示在 MATLAB 如何使用 LIME 进行复杂机器学习模型预测结果的解释。 我使用数据集 carbig&#xff08;MATLAB 自带的数据集&#xff09;训练一个回归模型&#xff0c;用于预测汽车的燃油效率。数据集 carbig 是 70 年代到 80 年代生产的汽…

ros2在启动前准备工作:

ros2的准备工作就是&#xff1a;setup.bash内容等价于setup.sh 文件存放路径&#xff1a;/opt/ros/humble/ # generated from ament_package/template/prefix_level/local_setup.sh.in# since a plain shell script cant determine its own path when being sourced # either…

Dockerfile的ENV

文章目录 环境总结测试测试1测试2测试3测试4测试5测试6 参考 环境 RHEL 9.3Docker Community 24.0.7 总结 如果懒得看测试的详细信息&#xff0c;可以直接看结果&#xff1a; 一条 ENV 指令可以定义多个环境变量。Dockerfile里可以包含多条 ENV 指令。环境变量的值不需要用…

游戏开发中,你的游戏图片压缩格式使用ASTC了吗

文章目录 ASTC原理&#xff1a;使用要求 ASTC&#xff08;Adaptive Scalable Texture Compression&#xff0c;自适应可伸缩纹理压缩&#xff09;是一种高级的纹理压缩技术&#xff0c;由ARM公司开发并推广。它在图形处理领域中因其出色的压缩效率和灵活性而受到广泛关注。 AST…

[Linux] 一文理解HTTPS协议:什么是HTTPS协议、HTTPS协议如何加密数据、什么是CA证书(数字证书)...

之前的文章中, 已经分析介绍过了HTTP协议. HTTP协议在网络中是以明文的形式传输的. 无论是GET还是POST方法都是不安全的. 为什么不安全呢? 因为: HTTP协议以明文的形式传输数据, 缺乏对信息的保护. 如果在网络中传输数据以明文的形式传输, 网络中的任何人都可以轻松的获取数据…

软件装一送三了!还附带弹窗资讯,你确定不试一下?

前言 前几天一个朋友向我吐槽&#xff0c;说电脑太卡了。自己好像都没安装什么软件&#xff0c;怎么就那么多弹窗广告。 我看了一下他的电脑&#xff0c;笑了一下说&#xff1a;你的电脑真好&#xff0c;都会只能给你推荐美女看&#xff0c;这资讯来之不易啊&#xff0c;好好享…

20240105-工作安排的最大收益

题目要求 我们有 n 份工作&#xff0c;每份工作都安排在 startTime[i] 至 endTime[i] 期间完成&#xff0c;从而获得 profit[i] 的利润。 给你 startTime、endTime 和 profit 数组&#xff0c;返回你能获得的最大利润&#xff0c;使得子集中没有两个时间范围重叠的工作。 如…

【C++】几种常用的类型转换

类型转换 c语言中的类型转换C的类型转换static_castreinterpret_castconst_castdynamic_cast c语言中的类型转换 在C语言中我们经常会遇到类型转化的问题&#xff0c;主要分为两种&#xff1a;显式类型转换和隐式类型转换。 显式类型转换&#xff1a;就是程序员使用强制类型转…

Kali Linux——设置中文

【问题现象】 从下图可以看到&#xff0c;菜单全是英文的。对于英文不好的同学&#xff0c;使用起来很难受。 【解决方法】 1、获取root权限 su root 2、进入语言设置 dpkg-reconfigure locales 3、选择zh_CN.UTF-8 UTF-8 4、设置默认 5、安装完成 6、重启虚拟机 reboot…

关于java的多维数组

关于java的多维数组 在前面的文章中&#xff0c;我们了解了数组的使用&#xff0c;我们之前所了解的数组是一维数组&#xff0c;本篇文章我们来了解一下二维数组&#xff0c;多维数组&#x1f600; 一、二维数组 首先我们知道一维数组的声明和创建的方式是。 int array ne…

Mysql SQL审核平台Yearning本地部署

文章目录 前言1. Linux 部署Yearning2. 本地访问Yearning3. Linux 安装cpolar4. 配置Yearning公网访问地址5. 公网远程访问Yearning管理界面6. 固定Yearning公网地址 前言 Yearning 简单, 高效的MYSQL 审计平台 一款MYSQL SQL语句/查询审计工具&#xff0c;为DBA与开发人员使用…

Python和Java环境搭建

小白搭建全流程 首先不建议装在C盘&#xff0c;一旦重置电脑&#xff0c;之前安装第三方包需要重新安装 relolver :解释器 1、Python解释器安装 资源包&#xff1a; 1、 python -version java -version–用于查看是否安装 where python whrer java–用于查看安装的位置【非常…