java并发之同步工具类一之闭锁Latch

本文详细介绍了Java中闭锁(Latch)的概念与应用场景,并通过一个跑步比赛的例子展示了如何使用闭锁来确保所有线程都在同一时刻开始执行。

java同步工具类(指jdk1.5版本)主要有闭锁(Latch)、信号灯(semaphore)和栅栏(barrier)。本篇作为开篇,先讲闭锁。闭锁就相当于一扇门,在制定的线程到达后这扇门才打开,后续所有线程可以通过,否则就一直处于阻塞状态。用于确保某些活动(这里可以理解为子线程)都完成后再继续执行下去(主线程)。如游戏中所有玩家就绪后才能点击开始,测试并发代码块真正的执行时间等(当我们在测试多线程的时候,总会有部分线程先启动,部分后启动,毕竟创建线程本身也需要时间,也就是多个线程会处在不同的初始条件下,这样测试出来的执行时间会有偏差,特别是线程非常多的时候,而闭锁可以在先启动的线程会等到所有后面启动的线程都启动完毕后再一起开始)。
如下面的代码引用了一个同样的场景——跑步比赛,只有所有运动员sprotMan都准备就绪后,裁判judge才能执行开始比赛。当所有运动员都结束比赛(到达终点或者放弃比赛),整场比赛才算结束。

import java.util.concurrent.CountDownLatch;

/**
 *
 * @author Jerry 比赛与Latch
 * @date 2017/12/24 0024
 */
public class Judge {
    public static void main(String[] args) {
        int joinMatchCnt = 5;//参加比赛的人数
        CountDownLatch beginMatchFlag = new CountDownLatch(1);
        CountDownLatch finishFlag = new CountDownLatch(joinMatchCnt);
        System.out.println("比赛准备开始.....");
        for (int i = 1; i <= joinMatchCnt; i++) {
            Thread t = new Thread(new Sportsman(beginMatchFlag, finishFlag, i + "号"));
            System.out.println("运动员"+i + "号已就位");
            t.start();//所有运动员都到指定位置就绪
        }
        beginMatchFlag.countDown();//裁判吹哨
        try {
            finishFlag.await();//裁判等待运动员跑完
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("比赛结束.....");
    }

    static class Sportsman implements Runnable {
        private CountDownLatch beginMatchFlag;
        private CountDownLatch finishFlag;
        private String name;

        public Sportsman(CountDownLatch beginMatchFlag, CountDownLatch finishFlag, String name) {
            this.beginMatchFlag = beginMatchFlag;
            this.finishFlag = finishFlag;
            this.name = name;
        }

        @Override
        public void run() {
            try {
                beginMatchFlag.await();//等待裁判比赛开始
                try {
                    running();
                } finally {
                    finishFlag.countDown();//运动员跑到终点,这里要放在finally中,如运动员跑步受伤,立即终止个人成绩
                }
                System.out.println("运动员" + name + "跑到终点线");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }

        private void running() {
            try {
                System.out.println("运动员" + name + "开始比赛");
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

运行的结果如下

比赛准备开始.....
运动员1号已就位
运动员2号已就位
运动员3号已就位
运动员4号已就位
运动员5号已就位
运动员1号开始比赛
运动员2号开始比赛
运动员3号开始比赛
运动员4号开始比赛
运动员5号开始比赛
运动员1号跑到终点线
运动员3号跑到终点线
运动员2号跑到终点线
运动员4号跑到终点线
运动员5号跑到终点线
比赛结束.....
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值