[英]Awaiting pool to finish threads
StopWatch sw = new StopWatch();
sw.start();
ExecutorService executor = Executors.newFixedThreadPool(MYTHREADS);
for (int i = 0; i < MYTHREADS; i++) {
Runnable worker = new SingleConnectionRunnable();
executor.execute(worker);
}
sw.stop();
System.out.println("total time"+sw.toString());
sw.reset();
sw.start();
for (int i = 0; i < MYTHREADS; i++) {
Runnable worker2 = new PooledConnectionRunnable();
executor.execute(worker2);
}
executor.shutdown();
executor.awaitTermination(Integer.MAX_VALUE, TimeUnit.SECONDS);
while (!executor.isTerminated()) {
}
sw.stop();
System.out.println("total time"+sw.toString());
我試圖在上面的代碼上運行一些性能測試。 我試圖在不同的Runnable
上使用同一executor
,並測量時間。 但這並不完全有效。 第一個“總時間”不正確,以毫秒為單位。
我想在第一個循環上打印經過的時間,然后打印第二個循環。 不知道如何等待執行程序完成第一個執行程序,然后重新啟動執行程序。
完成這項工作的正確方法是什么?
首先, awaitTermination
將阻塞,直到所有任務終止。 在等待可能的70年后,是否有任何特定原因需要使用while循環檢查?
無論如何,為了回答您的問題,為了等待第一次運行完成,您應該使用CountDownLatch
來表示每個線程的完成,並在主線程中等待它們完成。 您還可以使用CyclicBarrier
等待所有線程准備就緒,然后再開始計時,如下所示:
...
CountDownLatch latch = new CountDownLatch(MYTHREADS);
CyclicBarrier cb = new CyclicBarrier(MYTHREADS, new Runnable() {
@Override public void run() {
sw.start();
}
});
for (...) {
Runnable worker = ...
executor.execute(new Runnable() {
@Override public void run() {
try {
cb.await();
} catch (Exception e) {
throw new RuntimeException(e);
}
worker.run();
latch.countDown();
}
});
}
latch.await();
sw.stop();
...
我將sw.start()
移到了for循環的開頭,以避免測量要設置的對象分配開銷(由於以毫秒為單位,因此無論如何也無法測量)。
您還可以將兩個並發類重置為無限期運行。
您現在正在做的是:
您不必像第二個循環那樣等待它們完成。
這是您可以解決此問題的方法。
在SingleConnectionRunnable中創建一個回調方法。
該方法將在此可運行對象的最后一點(終止時)被調用,並被啟動循環的類捕獲(這不是問題中的方法,但可以)。
在此回調方法中,您要跟蹤它被調用了多少次。
當它被稱為MYTHREAD時,您將打印秒表時間。
現在您知道完成所有啟動的線程將花費多長時間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.