2017-09-14 4 views
0

안녕하세요, 아래 코드를 실행하려고하고 있는데, Executor가 종료 된 후에 남아있는 작업의 수가 0이 될 것으로 기대하고 있습니다. 그러나 어떤 이유로 인해 아래 조건을 만족하면 100이됩니다.Executors가 모든 작업을 완료하지 못했습니다.

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

코드 스 니펫.

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

100,000 개의 작업에 대한 출력.

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

와 synchronizedSet를 만들 수 있습니다,하지만 난 Executors.newFixedThreadPool (2000) '와 스레드 2 천 만드는 것을 알고 ...'문제에 대한 요구하고 내가 왜 궁금하네요 –

+1

을 이것은 HashSet이 동기화되지 않았기 때문에 ConcurrentModificationException으로 종료되지 않습니다 ... –

+0

@ G.Demecki ExecutorService executor = Executors.newFixedThreadPool (10);로 변경했습니다. 남은 총 작업은 2000보다 많습니다. –

답변

1

HashSet은 스레드로부터 안전하지 않습니다. 당신은 내가 모르는

public static volatile Set<String> task = Collections.synchronizedSet(new HashSet<String>()); 
관련 문제