CountDownLatch-使用

时间:2024-04-22 14:03:46

简单使用

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();
        }

    }
}