关闭 ScheduledExecutorService 是否安全?
Is it safe to shut down ScheduledExecutorService?
我正在实施一项服务,该服务执行一些更长的 运行 任务,由 Thread.sleep(10000)
此处模拟。当我 ctrl+c 执行时,我从来没有得到我期望的 InterruptedException
。我想知道为什么。
package simple;
import my.util.Now;
import io.dropwizard.lifecycle.Managed;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class EmailSender implements Managed {
private static final Logger LOGGER = LoggerFactory.getLogger(EmailSender.class);
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3);
// Constructor
public EmailSender() {}
@Override
public void start() {
LOGGER.info("Starting email sender thread: {}", Thread.currentThread().getName());
Runnable task = () -> {
LOGGER.info("Running: {} in thread: {}", Now.now(), Thread.currentThread().getName());
try {
Thread.sleep(10000);
} catch (InterruptedException ie) {
LOGGER.error("Task is being interrupted: {}", ie.getMessage());
}
};
executorService.scheduleAtFixedRate(task, 0, 5, TimeUnit.SECONDS);
}
@Override
public void stop() {
LOGGER.info("Stopping email sender thread: {}", Thread.currentThread().getName());
executorService.shutdown();
}
}
假设 executorService.shutdown();
以这种方式等待任务执行结束是否安全?
shutdown
不会终止当前 运行 任务,它甚至会执行队列中等待的任务。
如果您想立即终止,请使用shutdownNow
。
Is this safe to assume that executorService.shutdown(); waits till the execution is over for the task this way?
没有。它不会等待所有线程完成。
来自 ExecutorService 的 oracle 文档页面的推荐方法:
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
shutdown():
启动有序关闭,执行之前提交的任务,但不会接受新任务。
shutdownNow():
尝试停止所有正在执行的任务,停止等待任务的处理,并returns列出等待执行的任务。
你可以改变
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
到
while (!pool.awaitTermination(60, TimeUnit.SECONDS))
Thread.sleep(60000);
我正在实施一项服务,该服务执行一些更长的 运行 任务,由 Thread.sleep(10000)
此处模拟。当我 ctrl+c 执行时,我从来没有得到我期望的 InterruptedException
。我想知道为什么。
package simple;
import my.util.Now;
import io.dropwizard.lifecycle.Managed;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class EmailSender implements Managed {
private static final Logger LOGGER = LoggerFactory.getLogger(EmailSender.class);
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(3);
// Constructor
public EmailSender() {}
@Override
public void start() {
LOGGER.info("Starting email sender thread: {}", Thread.currentThread().getName());
Runnable task = () -> {
LOGGER.info("Running: {} in thread: {}", Now.now(), Thread.currentThread().getName());
try {
Thread.sleep(10000);
} catch (InterruptedException ie) {
LOGGER.error("Task is being interrupted: {}", ie.getMessage());
}
};
executorService.scheduleAtFixedRate(task, 0, 5, TimeUnit.SECONDS);
}
@Override
public void stop() {
LOGGER.info("Stopping email sender thread: {}", Thread.currentThread().getName());
executorService.shutdown();
}
}
假设 executorService.shutdown();
以这种方式等待任务执行结束是否安全?
shutdown
不会终止当前 运行 任务,它甚至会执行队列中等待的任务。
如果您想立即终止,请使用shutdownNow
。
Is this safe to assume that executorService.shutdown(); waits till the execution is over for the task this way?
没有。它不会等待所有线程完成。
来自 ExecutorService 的 oracle 文档页面的推荐方法:
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
shutdown():
启动有序关闭,执行之前提交的任务,但不会接受新任务。
shutdownNow():
尝试停止所有正在执行的任务,停止等待任务的处理,并returns列出等待执行的任务。
你可以改变
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
到
while (!pool.awaitTermination(60, TimeUnit.SECONDS))
Thread.sleep(60000);