怎么关闭线程池?
可以通过调用线程池的shutdown或shutdownNow方法来关闭线程池。它们的原理是遍历线程池中的工作线程,然后逐个调用线程的interrupt方法来中断线程,所以无法响应中断的任务可能永远无法终止。
shutdown:将线程池状态置为shutdown,并不会立即停止:
- 停止接收外部submit的任务
- 内部正在跑的任务和队列里等待的任务,会执行完
- 等到第二步完成后,才真正停止
shutdownNow:将线程池状态置为stop。一般会立即停止,事实上不一定:
- 和shutdown()一样,先停止接收外部提交的任务
- 忽略队列里等待的任务
- 尝试将正在跑的任务interrupt中断
- 返回未执行的任务列表
shutdown 和shutdownnow区别如下:
- shutdownNow:能立即停止线程池,正在跑的和正在等待的任务都停下了。这样做立即生效,但是风险也比较大。
- shutdown:只是关闭了提交通道,用submit()是无效的;而内部的任务该怎么跑还是怎么跑,跑完再彻底停止线程池。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* @author 百里
*/
public class BaiLiShutdownDemo {
public static void main(string[] args) {
// 创建一个线程池,包含两个线程
ExecutorService executor = Executors.newFixedThreadPool(2);
// 提交任务到线程池
executor.submit(() -> {
try {
Thread.sleep(30000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Task 1 finished");
});
executor.submit(() -> {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
System.out.println("Task 2 finished");
});
// 关闭线程池
executor.shutdown();
while (!executor.isTerminated()) {
System.out.println("Waiting for all tasks to finish...");
try {
// 每500毫秒检查一次
Thread.sleep(500);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
System.out.println("All tasks finished");
}
}
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* @author 百里
*/
public class BaiLiShutdownNowDemo {
public static void main(String[] args) {
// 创建一个线程池,包含两个线程
ExecutorService executor = Executors.newFixedThreadPool(2);
// 提交任务到线程池
executor.submit(() -> {
while (!Thread.interrupted()) {
System.out.println("Task 1 running...");
}
System.out.println("Task 1 interrupted");
});
executor.submit(() -> {
while (!Thread.interrupted()) {
System.out.println("Task 2 running...");
}
System.out.println("Task 2 interrupted");
});
// 关闭线程池
List<Runnable> unfinishedTasks = null;
executor.shutdownNow();
try {
// 等待直到所有任务完成或超时60秒
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
// 如果等待超时,则记录未完成的任务列表
unfinishedTasks = executor.shutdownNow();
System.out.println("Some tasks were not finished");
}
} catch (InterruptedException e) {
// 如果等待过程中发生异常,则记录未完成的任务列表
unfinishedTasks = executor.shutdownNow();
Thread.currentThread().interrupt();
}
if (unfinishedTasks != null && !unfinishedTasks.isEmpty()) {
System.out.println("Unfinished tasks: " + unfinishedTasks);
} else {
System.out.println("All tasks finished");
}
}
}