2017-09-14 95 views
0

您好我想運行下面的代碼,並且在執行器被終止後,我期待剩餘任務的計數爲0,但由於某種原因,當它滿足以下條件時它超過100。執行器沒有完成所有的任務

while(executor.isTerminated()) { 
       System.out.println("Total Task Remaining : " + ExecutorServiceExample.task.size()); 
       System.out.println("*** Executor Terminated ***"); 
       break; 
      } 

Code Snippet。

package test; 
import java.util.HashSet; 
import java.util.Set; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

public class ExecutorServiceExample { 

    public static volatile Set<String> task = new HashSet<String>(); 

    public static void main(String args[]) { 

     ExecutorService executor = Executors.newFixedThreadPool(2000); 

     for (int i = 0; i < 10000; i++) { 
      String name = "task#" + i; 
      task.add(name); 
      Runnable runner = new TaskPrint(name); 
      executor.execute(runner); 
     } 

     try { 
      executor.shutdown(); 
      executor.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS); 
      if (executor.isTerminated()) { 
       System.out.println("Total Task Remaining : " + ExecutorServiceExample.task.size()); 
       System.out.println("*** Executor Terminated ***"); 
      } 
     } catch (InterruptedException ignored) { 
     } 
    } 
} 

class TaskPrint implements Runnable { 

    private final String name; 

    public TaskPrint(String name) { 
     this.name = name; 
    } 

    public void run() { 
     ExecutorServiceExample.task.remove(name); 
    } 
} 

基於任務數量的結果有些奇怪。

100個任務的輸出。

Total Task Remaining : 0 
*** Executor Terminated *** 

1000個任務的輸出。

Total Task Remaining : 0 
*** Executor Terminated *** 

10000個任務的輸出。

Total Task Remaining : -27 
*** Executor Terminated *** 

100000個任務的輸出。

Total Task Remaining : 1205 
*** Executor Terminated *** 
+0

一個synchronizedSet我不知道,但我知道,創建2個數千個線程與'Executors.newFixedThreadPool(2000年);'是自找麻煩... –

+1

我不知道爲什麼因爲HashSet不同步... –

+0

@ G.Demecki我將它改爲'ExecutorService executor = Executors.newFixedThreadPool(10);'現在剩餘的總任務多於2000 –

回答

1

HashSet不是線程安全的。您可以創建

public static volatile Set<String> task = Collections.synchronizedSet(new HashSet<String>()); 
相關問題