2017-09-14 50 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>()); 
相关问题