Java 判断线程池所有任务是否执行完毕的操作
作者:ponhjl 时间:2021-10-03 09:43:55
我就废话不多说了,大家还是直接看代码吧~
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Test {
public static void main(String args[]) throws InterruptedException {
ExecutorService exe = Executors.newFixedThreadPool(3);
for (int i = 1; i <= 5; i++) {
exe.execute(new SubThread(i));
}
exe.shutdown();
while (true) {
if (exe.isTerminated()) {
System.out.println("结束了!");
break;
}
Thread.sleep(200);
}
}
}
上面是主线程的代码,创建了一个能同时执行2个线程的线程池,并投入5个线程,当5个线程都执行完毕后打印---“结束了!”字符串。
exe.shutdown();该方法在加入线程队列的线程执行完之前不会执行。exe.isTerminated()当shutdown()或者shutdownNow()执行了之后才会执行,并返回true。
在上面的代码中必须有exe.isTerminated()的判断,否则在投入5个线程到线程池后会直接打印:“结束了”。不能达到我们想要的效果。
通过while(true)循环判断exe.isTerminated()的值,为了防止过多的判断浪费资源,可设置线程睡眠Thread.sleep(200);正是由于这个睡眠,所以当所有线程池中的线程都执行完后,有可能延迟200ms才执行"结束了"语句。这个参数越小延迟越小,结果越准确。
下面是子线程,子线程只是简单的将数字i打印出来;
public class SubThread extends Thread{
private final int i;
public SubThread(int i){
this.i = i;
}
@Override
public void run(){
System.out.println(i);
}
}
执行结果:
3
1
4
5
2
结束了!
成功构建 (总时间: 2 秒)
子线程执行顺序不能控制,所以输出的结果是乱序的。
补充知识:java如何禁掉反射
SecurityManager
有一个checkMemberAccess这个方法可以阻止利用反射;
如:
SecurityManager sm = new SecurityManager();
sm.checkMemberAccess(Test.class, Member.PUBLIC);
前面一个为CLASS,后面需要填一个INT值,Member.PUBLIC 代表可以访问,
如果是PUBLIC,反射可以执行,DECLARED,反射运行时,会报错。
SecurityManager另外一个例子:
package com.jd.basic.pk.manager;
import java.lang.reflect.Field;
import java.security.Permission;
public class UseReflection {
static {
try {
System.setSecurityManager(new MySecurityManager());
} catch (SecurityException se) {
System.out.println("SecurityManager already set!");
}
}
public static void main(String args[]) {
Object prey = new Prey();
try {
Field pf = prey.getClass().getDeclaredField("privateString");
pf.setAccessible(true);
pf.set(prey, "Aminur test");
System.out.println(pf.get(prey));
} catch (Exception e) {
System.err.println("Caught exception " + e.toString());
}
}
}
class Prey {
@SuppressWarnings("unused")
private String privateString = "privateValue";
}
class MySecurityManager extends SecurityManager {
public void checkPermission(Permission perm) {
if (perm.getName().equals("suppressAccessChecks")) {
throw new SecurityException("Can not change the permission dude.!");
}
}
}
来源:http://blog.chinaunix.net/uid-29368697-id-4065665.html
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Eureka源码阅读之环境搭建及工程结构
![](https://img.aspxhome.com/file/2023/6/57946_0s.png)
SpringCloud Eureka应用全面介绍
![](https://img.aspxhome.com/file/2023/3/79953_0s.png)
java1.8安装及环境变量配置教程
![](https://img.aspxhome.com/file/2023/3/65153_0s.png)
Java语法基础之运算符学习笔记分享
![](https://img.aspxhome.com/file/2023/6/71866_0s.png)
C# 中string.split用法详解
Java如何利用状态模式(state pattern)替代if else
![](https://img.aspxhome.com/file/2023/7/87207_0s.jpg)
Android处理图像数据转换的各种方法
.net使用Aspose.Words进行Word替换操作的实现代码
![](https://img.aspxhome.com/file/2023/7/102187_0s.png)
Android基于opencv实现多通道分离与合并
![](https://img.aspxhome.com/file/2023/8/110758_0s.gif)
Android实现简单音乐播放器(MediaPlayer)
![](https://img.aspxhome.com/file/2023/5/102605_0s.png)
用Newtonsoft将json串转为对象的方法(详解)
C#二维数组与多维数组的具体使用
![](https://img.aspxhome.com/file/2023/5/82185_0s.jpg)
java实现双色球抽奖算法
![](https://img.aspxhome.com/file/2023/3/60543_0s.jpg)
如何使用Spring AOP的通知类型及创建通知
![](https://img.aspxhome.com/file/2023/2/61242_0s.png)
Android Zxing 转换竖屏扫描且提高识别率的方法
Java图形用户界面设计(Swing)的介绍
![](https://img.aspxhome.com/file/2023/4/75654_0s.jpg)
Java微信支付-微信红包
![](https://img.aspxhome.com/file/2023/6/66166_0s.png)
C#自定义控件实现TextBox禁止粘贴的方法
解决java读取EXCEL数据变成科学计数法的问题
![](https://img.aspxhome.com/file/2023/5/83675_0s.png)