如何使用关闭钩子优雅地停止Guava AbstractScheduledService?

Urj*_*jit 4 java service multithreading guava shutdown-hook

我正在使用带调度程序的AbstractScheduledService.一个简单的模式,如:

class MyService extends AbstractScheduledService {

   // KEEP THIS VAR IN MIND W.R.T the SHUTDOWN_HOOK BELOW
   public static volatile boolean keepRunning = true;

   protected void startUp() throws Exception {
     // startup stuff
   }

   protected void runOneIteration() throws Exception {
     // main logic stuff
   }

   protected void shutDown() throws Exception {
     // shutdown stuff
   }

   protected Scheduler scheduler() {
     return Scheduler.newFixedRateSchedule(0, 1, TimeUnit.SECONDS);
   }
 }
Run Code Online (Sandbox Code Playgroud)

现在,我想实现一个典型的关闭钩子:(下面的代码片段将在main方法中)

final Thread mainThread = Thread.currentThread();
        LOGGER.debug("Adding the shutdown hook");
        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                keepRunning = false;
                LOGGER.debug("The shutdown hook was engaged. Setting keepRunnning to false.");
                try {
                     // Is this appropriate?
                     mainThread.join();
                } catch (InterruptedException e) {
                    // handle exception here
                }
            }
        });
Run Code Online (Sandbox Code Playgroud)

关闭钩子来自典型的docs示例.由于服务本身在不同的线程上运行,因此它似乎与Guava服务模式不兼容.

我的服务在runOneIteration()逻辑中有一个轮询循环.我希望它完成它当前的任务,然后当看到keepRunning现在为false时正常关闭,因为Shutdown钩子在最近一段时间忙于其当前迭代时被使用了.

任何想法如何优雅地完成(完成当前迭代然后关闭)?

小智 6

你不能只调用stopAndWait()吗?

Runtime.getRuntime().addShutdownHook(new Thread() {
        @Override
        public void run() {
            service.stopAsync().awaitTerminated(60, TimeUnit.SECONDS);
        }
});
Run Code Online (Sandbox Code Playgroud)

  • @Urjit AbstractScheduledService可以在任何runOneIteration调用之间停止,但不能在调用期间停止(这是不可能的).如果您不希望服务能够在迭代之间停止,那么您最好使用AbstractExecutionThreadService并自行编码循环. (2认同)