执行人没有完成所有任务

时间:2017-09-14 06:20:58

标签: java runnable executorservice executor

您好我正在尝试运行以下代码,并且在执行程序终止后我希望剩余任务的计数为0,但由于某种原因,当它满足以下条件时它会超过100。

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

输出100000个任务。

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

1 个答案:

答案 0 :(得分:1)

HashSet不是线程安全的。您可以使用

创建synchronizedSet
public static volatile Set<String> task = Collections.synchronizedSet(new HashSet<String>());