2015-04-27 20 views
4

您可以考慮爲什麼此代碼無法正常工作並始終輸出「已完成」的任何原因,但第二個示例沒有任何問題。我正在使用最新的JDK(8u45)。ExecutorService workStealingPool和取消方法

 
public static class MyClass implements Runnable { 

     @Override 
     public void run() { 
      try { 
       Thread.sleep(2000); 
      } catch (InterruptedException ex) { 
       System.out.println("Interrupted"); 
       return; 
      } 
      System.out.println("Finished"); 
     } 

     public static void main(String[] args) { 
      // spot the difference -> 
      ExecutorService executorService = Executors.newWorkStealingPool(4); 
      Future future = executorService.submit(new MyClass()); 
      Thread.sleep(100); 
      future.cancel(true); 
     } 
    } 

而下面的例子完美的作品:

 
public static class MyClass implements Runnable { 

     @Override 
     public void run() { 
      try { 
       Thread.sleep(2000); 
      } catch (InterruptedException ex) { 
       System.out.println("Interrupted"); 
       return; 
      } 
      System.out.println("Finished"); 
     } 

     public static void main(String[] args) { 
      ExecutorService executorService = Executors.newSingleThreadExecutor(); 
      Future future = executorService.submit(new MyClass()); 
      Thread.sleep(100); 
      future.cancel(true); 
     } 
    } 

編輯:添加返回和更新的睡眠時間和另一個例子。

+0

哇,這是令人不安的。在我的系統上(Java 1.8.0_45-b14,Linux 3.2.0-4-amd64),它不打印*任何東西。*就像你一樣,我發現只有newWorkStealingPool返回的ExecutorService有這個問題。我們中的一個人應該將其作爲錯誤提交。 – VGR

回答

4

這比我原來想象的要簡單。問題在於工作竊取池在內部使用ForkJoinPool,而ForkJoinTask不支持取消(true),因此在任務啓動後無法取消任務。

見Javadoc文檔():

mayInterruptIfRunning - this value has no effect in the default implementation 
    because interrupts are not used to control cancellation. 
+0

有多尷尬;我只是沒有等待睡眠(2000年)完成。無論如何,好的發現。這對知道有用。 – VGR

+0

回想起來,這更明顯,因爲「單線程執行者」意味着不需要分叉另一個線程。我很好奇,如果你使用.newFixedThreadPool(1) – djangofan

2

沒有辦法在Java中強制終止Thread。 (二十年前,Java 1.0試圖提供這種方法,結果證明它是行不通的;試圖做到這一點的方法已被棄用而沒有替換。)

您作爲Runnable的作者負責通過乾淨地終止您自己的方法來正確響應中斷。在你的情況下,你應該已經在catch-block中退出了你的run方法,但是你沒有;你讓方法的邏輯繼續超越catch-block。因此,即使線程中斷,方法的最後一條語句也會始終執行。

+0

我的錯誤。我剛剛從一些更復雜的代碼中提取了這個例子,並且忘記添加返回。我的問題的核心思想略有不同 - 請參閱編輯。 – JiriS