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.");
}
}
输出:
发起者 入门 入门 入门 入门 入门 入门 Completed` 入门 入门 开始
在上面的代码中,“完成”应该在“开始”6次后打印,因为锁存计数降低到5 - 0,为什么它总是第7或第8次?我明白了吗?
答案 0 :(得分:1)
您的线程池大小为2,而Processor
个线程需要3秒才能执行。
Processors
个帖子,两个都打印Started
,然后在3秒后完成。Started
并在3秒后完成。然后另外两个(第5和第6个)开始,打印Started
,3秒后,其中一个(或两个)完成。在这一点上,有很多事情会在大致相同的时间发生(因此订单是随机的):
Completed
Processor
个主题并打印Started
Processor
个帖子并打印Started
因此,Completed
始终会打印出6,7或8 Started
张。
答案 1 :(得分:0)
所以,CountDownLatch
并不能保证它会在Count Down进入{{1}后立即恢复父线程(这里我指的是你调用latch.await();
的线程) }。因此,当Count Down锁定倒计时到0时会发生什么,这意味着现在父线程可以恢复其工作,这并不意味着它将获得CPU然后到那里。因此,它可以恢复,这并不意味着CPU在倒计时到0
时就会安排父线程。如果还有其他线程,则有可能在父线程之前执行。 在您的情况下,它会确保它不会0
before
时间打印5
,但会Started
ensure
exactly
5
1}}打印Started
次Completed
后。您可能还会观察到代码执行时Started
正在所有<ul>
打印结束时打印。