2017-01-31 56 views
0
運行

我有以下的代碼部分:查找出來,如果線程仍在線程池

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

我試圖檢查執行程序是否終止(),但只有在任務完成並關閉後返回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(),因爲沒有其他線程應該等待除主線程以外的此對象,但是如果您確實有其他線程,請使用後面的選項。