2017-04-13 75 views
3

我需要對具有零循環的長時間運行函數進行時間限制。我使用Callable運行該功能,並以超時值調用get。 AFAIU,future.cancel(true)將爲函數線程設置中斷標誌。但直到除非我檢查並處理longRunningFunction()中的Thread.isInterrupted(),我的代碼將不知道它必須退出,並且即使在shutdownNow()之後,該函數也不會終止。檢查java中的零循環線程中的中斷

  • 如何檢查中斷longRunningFunction()?該檢查需要立即進行,即如果將檢查放在特定點上,那麼直到這些點被點擊,線程將不處理該中斷。
  • 有沒有其他優美的方式來限時功能?
  • 爲什麼我不能殺死執行程序池中的所有線程?根據JavaDocs for ExecutorService,池將永遠不會終止,直到線程處理中斷並終止它們自己。
public class Test { 

    public void longRunningFunction() { 
    /* 
    Long running code without loop 
    */ 
    } 

    public Void call() { 
    try { 
     longRunningFunction() 
    } catch (InterruptedException exception) { 
     logger.error("{} Error : {}", TAG, exception.getStackTrace().join("\n")) 
    } catch (Exception exception) { 
     logger.error("[call]{} Error : {}", TAG, exception.getStackTrace().join("\n")) 
    } 
    } 

    public static void main(String[] args) { 
    ExecutorService executor = Executors.newSingleThreadExecutor() 
    Future<Void> future = executor.submit(new Test()) 
    int timeoutSeconds = 5 
    println "Setting timeout to " + timeoutSeconds 
    try { 
     future.get(timeoutSeconds, TimeUnit.SECONDS) 
    } catch (TimeoutException e) { 
     future.cancel(true) 
     logger.error("Could not finish processing within {} seconds", timeoutSeconds) 
    } finally { 
     executor.shutdownNow() 
     executor.awaitTermination(3, TimeUnit.SECONDS) 
     logger.error("Shutting down") 
    } 
    } 
} 

編輯 聯的標記複製的問題表明,共享變量是要走的路,這是因爲在問題中提到一個衆所周知的事實。問題是如何無縫檢查布爾標誌,例如Thread.isInterrupted

+0

即使'longRunningFunction'沒有循環也不合理,因爲在此函數中沒有檢查中斷標誌的中間步驟。 – freedev

+0

可能的重複[如何殺死Java中的線程?](http://stackoverflow.com/questions/671049/how-do-you-kill-a-thread-in-java) – freedev

+0

提到的鏈接表明,共享變量(這裏是「isInterrupted」標誌)是要走的路。這是一個已知的事實。問題是如何無縫檢查該布爾變量。 – ankshah

回答

1

超出檢查isInterrupted標誌的唯一方法是殺死線程,控制當前狀態並以某種方式協調它。你可以明顯地將它封裝在一個類中,使其顯示爲isInterrupted標誌已被檢查。