CountDownLatch介绍与实例说明

CountDownLatch是一个同步辅助类,使用时可以当做倒计时计数器来使用,创建对象时通过构造方法设置初始值,调用CountDownLatch对象的await()方法则处于等待状态,调用countDown()方法就将计数器减1,当计数到达0时,则所有等待者或单个等待者开始执行。

**构造方法摘要**
CountDownLatch(int count) 
构造一个用给定计数初始化的 CountDownLatch。   

**方法摘要**
void    await() 
使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断。
boolean await(long timeout, TimeUnit unit) 
使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的 等待时间。
void    countDown()  
递减锁存器的计数,如果计数到达零,则释放所有等待的线程。
long    getCount()  
返回当前计数。
String toString() 
返回标识此锁存器及其状态的字符串。

如下代码模拟吃货比赛,有十名吃货选手进行吃包子的比赛,设置一个开始计数锁,eatInitcountDownLatch ,初始值是1,比赛开始时,将调用countDown()方法来将计数器减一,选手线程中的await()方法感知到计数器已经到达0,就开始比赛, 设置一个结束计数锁,eatTotalcountDownLatch ,初始值是10,表明有10名选手进行比赛,一旦有一个选手吃完了所有的包子(30个),选手线程就调用eatTotalcountDownLatch .countDown()方法来将总数计数器减一,主类(比赛类)中的eatTotalcountDownLatch.await()方法一直处于阻塞状态,直到所有的选手都完成比赛,将总数计数器的值减为0时,出发比赛结束的操作。

CountDownLatchDemo.java 比赛主类

/**
 * 比赛
 * @author sunhf
 * @category runnable
 * */

package com.sun.comcurrent.countDownLatch.demo;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountDownLatchDemo
{
    public static final int FOODIE_COUNT = 10;

    public static void main(String[] args) throws InterruptedException
{
        // 定义一个线程池
ExecutorService executorService = Executors.newCachedThreadPool();
        // 设置开始计数锁
CountDownLatch eatInitcountDownLatch = new CountDownLatch(1);
        // 设置结束计数锁
CountDownLatch eatTotalcountDownLatch = new CountDownLatch(10);
        Foodie[] foodies = new Foodie[FOODIE_COUNT];
        for (int i = 0; i < FOODIE_COUNT; i++)
        {
        foodies[i] = new Foodie("吃货:" + i, eatInitcountDownLatch, eatTotalcountDownLatch);
        }
        System.out.println("各位吃货选手准备!");
        for (Foodie f : foodies)
            executorService.execute(f);//启动选手线程
        //无用 只是为了体现效果 休息6秒
        Thread.sleep(6000);

        System.out.println("比赛开始!");
        //开始计数锁 减一
        eatInitcountDownLatch.countDown();
        try
        {
        //结束计数锁 处于阻塞状态,等待计数变为0 执行
        eatTotalcountDownLatch.await();
        //无用 只是为了体现效果 休息6秒
        Thread.sleep(20);
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        } finally
        {
        System.out.println("比赛结束了!");
        }
        executorService.shutdown();
    }
}

Foodie.java 选手线程类:

package com.sun.comcurrent.countDownLatch.demo;

import java.util.concurrent.CountDownLatch;

/**
 * 吃货
 * 
 * @author sunhf
 * @category runnable
 * */
public class Foodie implements Runnable
{
    private String name;
    private CountDownLatch foodieInitCount;
    private CountDownLatch foodieTotalCount;

        public Foodie(String name, CountDownLatch       foodieInitCount, CountDownLatch foodieTotalCount)
    {
        this.name = name;
        this.foodieInitCount = foodieInitCount;
        this.foodieTotalCount = foodieTotalCount;
    }

    @Override
    public void run()
    {
        try
        {
            System.out.println( name + " 准备好了");
            //此时线程在阻塞状态,等待倒数锁到达0
            foodieInitCount.await();
            Long eatTime =(long) (Math.random() * 10000);
            Thread.sleep(eatTime);
            System.out.println(name + 
            " 玩命吃了30个包子,使用了 " + eatTime + "  秒");
        } catch (InterruptedException e)
        {
            e.printStackTrace();
        } finally
        {
        foodieTotalCount.countDown();//执行完毕,递减锁的计数器
        System.out.println( name + " 去吐了o(╯□╰)o");
        }
    }

}

执行结果:

各位吃货选手准备!
吃货:0 准备好了
吃货:2 准备好了
吃货:1 准备好了
吃货:4 准备好了
吃货:6 准备好了
吃货:3 准备好了
吃货:8 准备好了
吃货:5 准备好了
吃货:7 准备好了
吃货:9 准备好了
比赛开始!
吃货:5 玩命吃了30个包子,使用了 918  秒
吃货:5 去吐了........o(╯□╰)o
吃货:0 玩命吃了30个包子,使用了 1175  秒
吃货:0 去吐了........o(╯□╰)o
吃货:1 玩命吃了30个包子,使用了 1364  秒
吃货:1 去吐了........o(╯□╰)o
吃货:4 玩命吃了30个包子,使用了 1483  秒
吃货:4 去吐了........o(╯□╰)o
吃货:3 玩命吃了30个包子,使用了 2691  秒
吃货:3 去吐了........o(╯□╰)o
吃货:6 玩命吃了30个包子,使用了 3582  秒
吃货:6 去吐了........o(╯□╰)o
吃货:7 玩命吃了30个包子,使用了 3920  秒
吃货:7 去吐了........o(╯□╰)o
吃货:2 玩命吃了30个包子,使用了 6177  秒
吃货:2 去吐了........o(╯□╰)o
吃货:9 玩命吃了30个包子,使用了 7250  秒
吃货:9 去吐了........o(╯□╰)o
吃货:8 玩命吃了30个包子,使用了 7915  秒
吃货:8 去吐了........o(╯□╰)o
比赛结束了!选手们 还在吐....o(╯□╰)o
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值