为什么java中的Countdownlatch不能在给定的锁存计数时停止?
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class Processor implements Runnable {
private CountDownLatch latch;
public Processor(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
System.out.println("Started.");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
latch.countDown();
}
}
// -----------------------------------------------------
public class App {
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(5); // coundown from 5 to 0
ExecutorService executor = Executors.newFixedThreadPool(2); // 2 Threads in pool
for(int i=0; i < 10; i++) {
executor.submit(new Processor(latch)); // ref to latch. each time call new Processes latch will count down by 1
}
try {
latch.await(); // wait until latch counted down to 0
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Completed.");
}
}
输出:
开始 起动 起动 起动 起动 起动 起动 完成` 起动 起动 开始
在上面的代码中,“已完成”应该在6次“开始”后打印,因为闩锁倒计时为5-0,为什么总是第7次或第8次?我理解错了吗
# 1 楼答案
你的线程池大小为2,你的
Processor
线程需要3秒钟才能执行Processors
线程启动,两个线程都打印Started
,并在3秒钟后完成李>Started
,并在3秒钟后完成李>然后另外两个(第五和第六个)开始打印
Started
,三秒钟后其中一个(或两个)完成。在这一点上,几乎同时会发生多件事情(因此顺序是随机的):Completed
Processor
线程启动并打印Started
Processor
线程启动并打印Started
因此,
Completed
前面总是有6、7或8Started
个打印输出# 2 楼答案
因此,
CountDownLatch
并不保证它会在倒计时一到0
就恢复父线程(这里我指的是调用latch.await();
的线程)的执行。所以,当倒计时闩锁倒计时为0时会发生什么,这意味着现在父线程可以继续工作,但这并不意味着它将获得CPU。因此,它可以恢复,这并不意味着CPU会在倒计时到0
时立即安排父线程。如果还有其他线程,那么这些线程可能会在父线程之前执行在您的情况下,它确保不会执行before
时间打印5
,但它确实会ensure
在打印5
次Started
后执行exactly
。您还可以在代码的某个特定执行时观察到Completed
在所有Started
打印结束时正在打印