2015-04-17 47 views
1

我正在使用單線程ScheduledExecutorService來處理一些Runnable任務。當我的Runnable完成其工作時,它會在ScheduledExecutorService中重新安排自己的延遲時間。這種情況無限期發生,直到Runnable獲得Exception關閉運行任務中的ExecutorService

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 
      } 
     } 
    } 
} 

我可以shutdown()shutdownNow()ExecutorService安全地從Task.run()?如果線程會引發自身的中斷,那麼某些東西看起來不正確。

當執行Task時發生異常時,我想shutdownservice,理想情況下調用Runner.stopWorking()

我知道我可以使用一個Callable,而不是讓Runner管理的重新安排,但我想保持這種結構(Runner將有更多類似的service S,這樣無限循環只是看起來不正確的存在)。

我想我可以繼承ScheduledThreadPoolExecutor覆蓋afterExecute並處理關機,使用對Runner的引用。

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

我的這種做法值得關注的是,如果afterExecute將由跑Task,這將具有相同的效果,從Task.run()本身調用shutDown()線程調用。

有沒有其他的替代方法呢?

+0

看起來像調用'shutdown()'或甚至'shutdownNow()'從任務本身是安全的,並且正常工作。如果確實如此,這個問題的答案是微不足道的。 –

回答

3

可以關閉()或shutdownNow()安全的ExecutorService從 Task.run()?如果線程將是 引發自身中斷,那麼某些東西看起來不正確。

shutdown()不會中斷已經運行的任務,但會阻止新的任務被引誘。 shutdownNow()也不會中斷正在運行的任務,而是「發信號通知」應該終止的所有工作人員。它是由Thread執行(或者更確切地說Runnable本身)它會否認這樣的信號(我記得Thread.isTerminated())或不。

是的,它是完全正常的線程信號自己被終止。所以shutdown()執行者對運行任務是安全的。

相關問題