找出线程是否仍在threadPool中运行

时间:2017-01-31 12:50:15

标签: java multithreading executorservice

我有以下部分代码:

protected ExecutorService parallelExecutor = Executors.newCachedThreadPool();
protected ExecutorService serialExecutor = Executors.newSingleThreadExecutor();
List<?> parallelCommands = new ArrayList<?>();
List<?> serialCommands = new ArrayList<?>();
List<Future<Boolean>> results = null;
LocalDateTime timed = LocalDateTime.now().plusSeconds(60);

results = parallelExecutor.invokeAll(parallelCommands);
results.addAll(serialExecutor.invokeAll(serialCommands));

现在我想检查两个执行者是否在超时内完成了他们的工作:

while (LocalDateTime.now().isBefore(timed)) {
 \\ here I need to check if meanwhile my threads finished
 \\ if yes, break;}

如何验证遗嘱执行人是否完成了工作?

2 个答案:

答案 0 :(得分:0)

JDK文档:

void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
    // Wait a while for existing tasks to terminate
    if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
       pool.shutdownNow(); // Cancel currently executing tasks
       // Wait a while for tasks to respond to being cancelled
       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
          System.err.println("Pool did not terminate");
    }
} catch (InterruptedException ie) {
    // (Re-)Cancel if current thread also interrupted
    pool.shutdownNow();
    // Preserve interrupt status
    Thread.currentThread().interrupt();
}

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#awaitTermination-long-java.util.concurrent.TimeUnit-

答案 1 :(得分:0)

使用计数器跟踪完成的每项任务。您可以通过修改添加到任务列表中的任务或使用CompletableFuture来减少和检查。

List<Callable<?>> tasks = ...
ExecutorService executor = ...

// Might want to add the size of your other task list as well
AtomicInteger counter = new AtomicInteger(tasks.size());

for (Callable<?> callable : tasks) {
    results.add(executor.submit(new Callable() {
        callable.call();
        int value = counter.decrementAndGet();

        if (value == 0) {
            synchronized (this) {
                OuterClass.this.notify();
            }
        }
    });
}
long timed = System.currentTimeMillis();

synchronized (this) {
    long timeLeft;

    // Or however many millis your timeout is
    while ((timeLeft = 60_000 - System.currentTimeMillis() - timed) > 0) {
        this.wait(timeLeft);
    }
}

您要做的是等到主线程上的时间不足,而执行程序执行您的任务。如果任务完成并且它意识到没有任务尚未完成,则它会告知等待的线程继续。我使用notify()而不是notifyAll()因为除了主线程之外没有其他线程应该等待这个对象,但如果你有其他线程,请使用后一个选项。