关闭ScheduledExecutorService是否安全?

时间:2016-07-16 09:29:52

标签: java multithreading executorservice

我正在实现一项服务,该服务执行一些由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();等待任务执行结束吗?

2 个答案:

答案 0 :(得分:2)

shutdown不会终止当前正在运行的任务,甚至会执行队列中等待的任务。

如果您想立即终止,请使用shutdownNow

答案 1 :(得分:1)

  

假设executorService.shutdown();是否安全?等待执行结束这样的任务?

没有。它不会等待所有线程的完成。

来自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():尝试停止所有正在执行的任务,停止等待任务的处理,并返回等待执行的任务列表。

您可以更改

if (!pool.awaitTermination(60, TimeUnit.SECONDS))

while (!pool.awaitTermination(60, TimeUnit.SECONDS))
Thread.sleep(60000);
相关问题