从正在运行的任务中关闭 ExecutorService

Xav*_*ica 1 java executorservice scheduledexecutorservice

我使用单线程ScheduledExecutorService来处理一些Runnable任务。当我的Runnable工作完成后,它会以ScheduledExecutorService可变的延迟重新安排自己。这种情况会无限期地发生,直到Runnable捕获到Exception。

public class Runner { 

    ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();

    public void startWorking() { 
        // Single-shot start
        service.submit(new Task(service));
    }

    public void stopWorking() { 
        service.shutDown();
        // Do some other stuff
    }

    private static final class Task implements Runnable { 
        ScheduledExecutorService service;
        private Task(ScheduledExecutorService service) {
            this.service = service;
        }
        @Override 
        public void run() { 
            try { 
                // Do some work...
                service.schedule(this, variableDelay, TimeUnit.SECONDS);
            }
            catch(SomethingHappenedException e){ 
                // Shutdown service
            }
        }
    }   
}
Run Code Online (Sandbox Code Playgroud)

我shutdown()或可以shutdownNow()安全ExecutorService离开Task.run()吗?如果线程会引发自身中断,那么事情看起来就不对劲。

当执行时捕获异常时Task,我希望最好shutdown调用.serviceRunner.stopWorking()

我知道我可以使用 aCallable来代替并让Runner管理重新安排,但我想保留这个结构(Runner将有更多类似的services,所以无限循环看起来并不正确)。

我想我可以ScheduledThreadPoolExecutor使用afterExecute对Runner.

public class Runner { 
    ScheduledExecutorService service = new ScheduledThreadPoolExecutor(1){
      protected void afterExecute(Runnable r, Throwable t) { 
        if (t != null) { 
            Runner.this.stopWorking();
        }
    };
    // ...
}
Run Code Online (Sandbox Code Playgroud)

我对这种方法的担忧是,如果afterExecute由运行 的线程调用,这将具有与从自身Task调用相同的效果。shutDown()Task.run()

还有其他替代方法吗?

Ant*_*sss 5

我可以从 Task.run() 安全地 shutdown() 或 shutdownNow() ExecutorService 吗?如果线程会引发自身中断,那么事情看起来就不对劲。

shutdown()不会中断已经运行的任务,但会阻止提交新任务。 shutdownNow()也不会中断正在运行的任务,而是向所有工作人员发出“信号”,表明他们应该被终止。是否尊重这样的信号(据我记得)取决于Thread实施(或者更确切地说它本身)。RunnableThread.isTerminated()

是的,线程向自己发出终止信号是完全可以的。shutdown()因此执行器运行任务是安全的。