1、shutdown() 方法的使用
public class ShutdownTest {
public static void main(String[] args) throws InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(2);
for (int i = 0; i < 5; i++) {
// lambda表达式内只能使用final变量,所以这里使用相同效果的String类
String str = i + "";
service.execute(() -> {
System.out.println(str);
});
}
service.shutdown();
System.out.println("线程池已关闭");
}
}
运行结果:
0
1
线程池已关闭
2
3
4
Process finished with exit code 0
从运行结果可以看出,在调用shutdown()方法后,已添加的任务会继续执行完毕,但是不会阻塞,导致 main 线程先打印出“线程池已关闭”。前面分析shutdown()方法时说过,调用该方法后线程池不再接收新的任务,那如果继续添加任务会怎样呢?把上述代码稍作修改
public static void main(String[] args) throws InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(2);
for (int i = 0; i < 5; i++) {
String str = i + "";
service.execute(() -> {
System.out.println(str);
});
}
service.shutdown();
// 调用shutdown()方法后继续添加任务
service.execute(() -> System.out.println("ok"));
System.out.println("线程池已关闭");
}
运行结果
0
1
3
2
4
Exception in thread "main" java.util.concurrent.RejectedExecutionException: ...
Process finished with exit code 1
可见如果在shutdown()方法调用后继续往线程池添加任务,会直接执行拒绝策略,而默认的拒绝策略是抛出异常。
2、shutdown() 和 awaitTermination() 组合使用
为保证执行顺序,一般会把shutdown()和 awaitTermination()方法组合使用,效果如下:
public static void main(String[] args) throws InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(2);
for (int i = 0; i < 5; i++) {
String str = i + "";
service.execute(() -> {
System.out.println(str);
});
}
// shutdown() 和 awaitTermination() 组合使用
service.shutdown();
service.awaitTermination(1, TimeUnit.MINUTES);
System.out.println("线程池已关闭");
}
运行结果
0
1
2
4
3
线程池已关闭
Process finished with exit code 0
这样就保证了线程池和其他线程的之间的执行顺序。
3、shutdownNow() 方法的使用
public class ShutdownNowTest {
public static void main(String[] args) throws InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(2);
for (int i = 1; i <= 5; i++) {
String str = i + "";
service.execute(new Runnable() {
@Override
public void run() {
System.out.println(str);
}
// 为了后面展示未执行的任务,这里重写toString()方法
@Override
public String toString() {
return "这是第" + str + "个任务";
}
});
}
// 没有来得及执行的任务会以列表的形式返回
List<Runnable> runnables = service.shutdownNow();
System.out.println("线程池已关闭");
for (Runnable runnable : runnables) {
// 打印一下未执行的任务
System.out.println(runnable);
}
}
}
运行结果:
1
2
线程池已关闭
这是第3个任务
这是第4个任务
这是第5个任务
Process finished with exit code 0
从运行结果可以看出,在调用shutdownNow()方法后,线程池会立即关闭,未执行的任务会以列表的形式返回。