JUC中可以通过Executors框架来实现线程池,可以创建一个固定大小的线程池,如下所示:
ExecutorService service = Executors.newFixedThreadPool(15);
关闭线程池有两种方法:shutdown()和shutdownNow(),两种方法的区别何在?
1.shutdown()
当调用了shutdown()方法时,便进入关闭状态,此时意味着 ExecutorService不再接受新的任务,但它还在执行已经提交了的任务,当已经提交了的任务执行完后,便到达终止状态。如果不调用 shutdown()方法,ExecutorService 会一直处在运行状态,不断接收新的任务,执行新的任务,服务器端一般不需要关闭它,保持一直运行即可。
2.shutdownNow()
阻止等待任务启动并试图停止当前正在执行的任务,即停止当前执行的task,并返回尚未执行的task的list。
下面介绍一段代码来优雅的关闭线程池:
private void closeExecutorThreadPoolGraceFully(ExecutorService executor) {
try {
executor.shutdown();
if(!executor.awaitTermination(SHUTDOWN_TIME, TimeUnit.SECONDS)) {
logger.info("Executor did not terminate in the specified time.");
List<Runnable> droppedTasks = executor.shutdownNow();
logger.info("Executors was abruptly shut down." + droppedTasks.size() + " tasks will not be executed.");
}
logger.info("scheduled executor service closed normally.");
} catch (InterruptedException e) {
logger.error("interrupted exception error...");
}
}
当然也可以启动一个线程来操作,异步操作效率可能更高:
private void closeExecutorThreadPoolGraceFully(ExecutorService executor) {
final ExecutorService executor;
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
executor.shutdown();
if (!executor.awaitTermination(SHUTDOWN_TIME)) {
Logger.log("Executor did not terminate in the specified time.");
List<Runnable> droppedTasks = executor.shutdownNow();
Logger.log("Executor was abruptly shut down. " + droppedTasks.size() + " tasks will not be executed.");
}
}
}
}