简单使用
public static void main(String[] args) throws InterruptedException {
CountDownLatch countDownLatch = new CountDownLatch(10);
for (int i = 0; i < 10; i++) {
int finalI = i;
new Thread(()->{
System.out.println(finalI);
countDownLatch.countDown();
}).start();
}
countDownLatch.await();
System.out.println("结束了");
}
- 在线程里使用,每次减少 1
- await后面的进程需要等到上面的进程执行完毕,才可以执行
问题?
如何使用CountDownLatch使得角色裁判,喊完各就位预备后,发枪,这个两个动作后,运动员才开始跑
需要使用callable接口,而不是runnable接口
复杂使用
裁判类 【Judge】
class Judge implements Callable<String>{
private CountDownLatch startCreamLatch;
private CountDownLatch startFireLatch;
public Judge(CountDownLatch startCreamLatch, CountDownLatch startFireLatch) {
this.startCreamLatch = startCreamLatch;
this.startFireLatch = startFireLatch;
}
@Override
public String call() throws Exception {
scream();
this.startCreamLatch.countDown();
this.startCreamLatch.await();
fire();
this.startFireLatch.countDown();
this.startFireLatch.await();
return "裁判发枪成功";
}
public void scream (){
System.out.println("裁判喊:各就位");
}
public void fire(){
System.out.println("开枪");
}
}
- 定义了scream的CountDownLatch 和 fire的 CountDownLatch
- 在主类中分别设置倒计时为1,每次执行完,即可以执行下一个
运动员类【runner】
class Runner implements Callable<String>{
private CountDownLatch startLatch;
public Runner(CountDownLatch startLatch) {
this.startLatch = startLatch;
}
@Override
public String call() throws Exception {
this.startLatch.await();
run();
return Thread.currentThread().getName() + "运动员正在运动";
}
public void run(){
System.out.println(Thread.currentThread().getName()+"运动员跑起来了");
}
}
主线程【main】
public class Game{
public static void main(String[] args) {
CountDownLatch startCreamLatch = new CountDownLatch(1);
CountDownLatch startFireLatch = new CountDownLatch(1);
Judge judge = new Judge(startCreamLatch,startFireLatch);
Runner runner = new Runner(startFireLatch);
FutureTask futureTask = new FutureTask(judge);
new Thread(futureTask).start();
for (int i = 0; i < 8; i++) {
FutureTask task = new FutureTask(runner);
new Thread(task,"第"+String.valueOf(i)+"运动员").start();
}
}
}