object Main extends App {
val poolSize = 2
val executor = Executors.newFixedThreadPool(poolSize)
val doneSignal = new CountDownLatch(poolSize)
(0 until poolSize).foreach{
i => executor.submit(new Work(doneSignal, i))
}
executor.shutdown()
println("Work submitted")
doneSignal.await()
println("Work completed")
}
class Work(doneSignal:CountDownLatch, id:Int) extends Runnable {
override def run(): Unit = {
println(s"Starting $id : ${Thread.currentThread().getName}")
Thread.sleep(3000)
println(s"Ending $id : ${Thread.currentThread().getName}")
doneSignal.countDown()
}
}
我很欣赏CountDownLatch是一个线程安全类,可以帮助进行线程间通信。但是对于上面显示的用例不是一个简单的
executor.awaitTermination(1, TimeUnit.DAYS)
足够?
答案 0 :(得分:4)
在你的例子中,使用它们应该没有区别。
初始化为N的CountDownLatch可用于使一个线程等待 直到N个线程完成某个动作或某个动作已完成N次。
线程不需要完成执行 - 只需按照同步要求完成某些操作 - 它们表示使用latch.countDown()完成;
对于示例 如果您在渲染UI之前从5个Web服务获取数据,则可以在单独的线程中执行此操作。一旦数据可用,渲染就可以开始,但是您的各个线程仍然继续执行以对该数据执行一些簿记操作。
ExecutorService.awaitTermination()要求线程完成执行。在你的情况下,他们会工作类似,但在下面的例子中,他们不会。
public class Test {
public static void main(String[] args) throws InterruptedException {
int count = 2;
ExecutorService ex = Executors.newFixedThreadPool(5);
CountDownLatch latch = new CountDownLatch(5);
for (int i = 1; i <= count; i++)
ex.execute(() -> {
String name = Thread.currentThread().getName();
System.out.println("Starting thread "+ name);
try { Thread.sleep(1000); } catch (Exception e) { }
System.out.println("Pre-Notification work completed "+ name);
latch.countDown();
try { Thread.sleep(1000); } catch (Exception e) { }
System.out.println("Post-Notification Work Completed"+ name);
}
);
latch.await();
//ex.shutdown();
//ex.awaitTermination(1, TimeUnit.DAYS);
System.out.println("Finishing Execution");
}
}
使用latch.await输出
Starting thread pool-1-thread-1
Starting thread pool-1-thread-2
Pre-Notification work completed pool-1-thread-1
Pre-Notification work completed pool-1-thread-2
Finishing Execution
Post-Notification Work Completedpool-1-thread-1
Post-Notification Work Completedpool-1-thread-2
使用awaitTermination输出
Starting thread pool-1-thread-2
Starting thread pool-1-thread-1
Pre-Notification work completed pool-1-thread-2
Pre-Notification work completed pool-1-thread-1
Post-Notification Work Completedpool-1-thread-1
Post-Notification Work Completedpool-1-thread-2
Finishing Execution