2017-01-31 7 views
0

я следующая часть кода:Выясните, если потоки по-прежнему работает в Threadpool

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;} 

Как проверить, завершили ли исполнители свою работу?

+0

Позвоните 'get' на фьючерсы. Готовые возвращаются немедленно. 'get' также можно вызвать с настройкой тайм-аута: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html#get-long-java.util.concurrent .TimeUnit- – Fildor

+0

Также может возникнуть причудливый способ сделать это с помощью CompleteableFuture ... – Fildor

ответ

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-

+0

Это имеет смысл только при выключении пулов. – Fildor

+0

Я попытался проверить, является ли исполнителем isTerminated(), но это возвращает true только в том случае, если задачи завершены и после этого завершается выключение. Кажется, что закрытие пула в этом случае не происходит. – Bianca

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(), потому что ни один другой поток не должен ждать этого объекта, кроме основного потока, но если у вас есть другие потоки, используйте последний вариант.

 Смежные вопросы

  • Нет связанных вопросов^_^