今天在项目中使用了线程池,发现不会把线程关闭掉,所以就看了这方面,并作个记录。
1、shutdown()和isTerminated()配合使用
目前项目中使用的shutdown()和isTerminated()配合使用。
shutdown()方法会关闭线程池,这个方法会等待正在运行和队列里的任务都执行完毕后,才会关闭线程池。
isTerminated()每次调用此方法都会返回一个boolean值,true表示线程已关闭,false表示线程池还在运行。此方法必须放在shutdown()方法之后,否则返回值一定为false。
System.out.println("开始");
ExecutorService executors = Executors.newFixedThreadPool(10);
for (int i = 0; i < 2; i++) {
executors.execute(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 3; j++) {
try {
System.out.println("正在运行的线程"+Thread.currentThread().getId()
+Thread.currentThread().getName()+j);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
System.out.println("执行shutdown");
executors.shutdown();
while (true) {
if (executors.isTerminated()) {
System.out.println("所有的子线程都结束了!");
break;
}
}
System.out.println("执行完毕");
运行结果
开始
执行shutdown
正在运行的线程12pool-1-thread-10
正在运行的线程13pool-1-thread-20
正在运行的线程13pool-1-thread-21
正在运行的线程12pool-1-thread-11
正在运行的线程13pool-1-thread-22
正在运行的线程12pool-1-thread-12
所有的子线程都结束了!
执行完毕
2、shutdown()和awaitTermination()配合使用
awaitTermination()方法,有两个参数,第一个是long类型的数值,第二个是时间类型TimeUnit,用于设置阻塞时间。
awaitTermination()方法是一个阻塞的方法,若线程池一直运行则会一直阻塞,直到线程池关闭返回true,或阻塞时间超过你设置的这个时间,则返回false。
此方法必须放在shutdown()方法之后,否则一直在阻塞,或超过设置的阻塞时间返回false。
可以有两种写法:
1、设置一个小的阻塞时间,循环调用awaitTermination()方法,来判断线程是否执行完毕。
System.out.println("开始");
ExecutorService executors = Executors.newFixedThreadPool(10);
for (int i = 0; i < 2; i++) {
executors.execute(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 3; j++) {
try {
System.out.println("正在运行的线程"+Thread.currentThread().getId()
+Thread.currentThread().getName()+j);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
System.out.println("执行shutdown");
executors.shutdown();
while (!executors.awaitTermination(1, TimeUnit.SECONDS)){
System.out.println("执行awaitTermination");
}
System.out.println("执行完毕");
运行结果:
开始
执行shutdown
正在运行的线程12pool-1-thread-10
正在运行的线程13pool-1-thread-20
正在运行的线程13pool-1-thread-21
正在运行的线程12pool-1-thread-11
执行awaitTermination
正在运行的线程13pool-1-thread-22
正在运行的线程12pool-1-thread-12
执行awaitTermination
执行完毕
2、设置一个超大的阻塞时间,一直阻塞,直到线程池执行完毕
System.out.println("开始");
ExecutorService executors = Executors.newFixedThreadPool(10);
for (int i = 0; i < 2; i++) {
executors.execute(new Runnable() {
@Override
public void run() {
for (int j = 0; j < 3; j++) {
try {
System.out.println("正在运行的线程"+Thread.currentThread().getId()
+Thread.currentThread().getName()+j);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
System.out.println("执行shutdown");
executors.shutdown();
System.out.println("执行awaitTermination");
executors.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
System.out.println("执行完毕");
运行结果:
开始
执行shutdown
正在运行的线程12pool-1-thread-10
正在运行的线程13pool-1-thread-20
执行awaitTermination
正在运行的线程12pool-1-thread-11
正在运行的线程13pool-1-thread-21
正在运行的线程12pool-1-thread-12
正在运行的线程13pool-1-thread-22
执行完毕
这样awaitTermination()方法只会返回一次,代码中就不需要写while循环。