CountDownLatch、CyclicBarrier、Semaphore代码理解

一、CountDownLatch

CountDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行
是通过一个计数器来实现的,计数器的初始值是线程的数量。
每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了

1.1 CountDownLatch1

package com.zhang;

import java.util.concurrent.CountDownLatch;

public interface CountDownLatch1 {
    public static void main(String[] args) {
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 0; i < 6; i++) {
            new Thread(()->{
                System.out.println("线程:"+Thread.currentThread().getName()+"\t离开商场");
                countDownLatch.countDown();
            },String.valueOf(i)).start();
        }
        try {
            countDownLatch.await();
            System.out.println("***************顾客都离开了,商场下班了,关门!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

执行结果
在这里插入图片描述

1.2 CountDownLatch2

利用枚举类实现

package com.zhang;

import java.util.concurrent.CountDownLatch;

public class CountDownLatch2 {
    public static void main(String[] args) {
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 1; i <= 6 ; i++) {
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"国,被灭!");
                countDownLatch.countDown();
            },CountryEnum.getCountry(i).getRetMessage()).start();
        }
        try {
            countDownLatch.await();
            System.out.println("秦国,一统天下!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

1.3 CountryEnum

枚举类:
继承了java.lang.Enum类!所以说,枚举类不能再继承其他类了,因为默认已经继承了Enum类。并且,这个类是final的!所以它不能被继承。

package com.zhang;

import lombok.Getter;

public enum CountryEnum {
    //枚举类
    ONE(1,"齐"),TWO(2,"楚"),THREE(3,"燕"),FOUR(4,"韩"),FIVE(5,"赵"),SIX(6,"魏");

    @Getter
    private Integer retCode;
    @Getter
    private String retMessage;

    CountryEnum(Integer retCode, String retMessage){
        this.retCode = retCode;
        this.retMessage = retMessage;
    }

    public static CountryEnum getCountry(int index){
        CountryEnum[] array = CountryEnum.values();//会返回包括所有枚举变量的数组
        for (CountryEnum element: array ) {
            if (element.getRetCode() == index){
                return  element;
            }
        }
        return null;
    }
}

测试结果
在这里插入图片描述

二、CyclicBarrier

循环栅栏,大概的意思就是一个可循环利用的屏障。
它的作用就是会让所有线程都等待完成后才会继续下一步行动

2.1 重要方法

public int await() throws InterruptedException, BrokenBarrierException
public int await(long timeout, TimeUnit unit) throws InterruptedException, BrokenBarrierException, TimeoutException

2.2 CountDownLatch和CyclicBarrier区别

CountDownLatch 是一次性的,CyclicBarrier 是可循环利用的
CountDownLatch 参与的线程的职责是不一样的,有的在倒计时,有的在等待倒计时结束。CyclicBarrier 参与的线程职责是一样的。

package com.zhang;

public class CyclicBarrier {
    public static void main(String[] args) {
        java.util.concurrent.CyclicBarrier cyclicBarrier = new java.util.concurrent.CyclicBarrier(7,()->{
            System.out.println("****收集7颗龙珠完毕****召唤神龙!");
        });

        for (int i = 1; i <=7 ; i++) {
            final int tempInt = i;
            new Thread(()->{
                System.out.println("线程:"+Thread.currentThread().getName()+"\t收集到第"+tempInt+"颗龙珠!");
                try {
                    cyclicBarrier.await();//线程调用 await() 表示自己已经到达栅栏
                }catch (Exception e){
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();

        }
    }
}

测试结果
在这里插入图片描述

三、Semaphore

是一个线程同步的辅助类,可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore可以控制同时访问资源的线程个数,例如,实现一个文件允许的并发访问数。

3.1 Semaphore主要方法

 void acquire():从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。
 void release():释放一个许可,将其返回给信号量。
  int availablePermits():返回此信号量中当前可用的许可数。
  boolean hasQueuedThreads():查询是否有线程正在等待获取。

3.2 Semaphore代码验证

package com.zhang;

import java.util.concurrent.TimeUnit;

public class Semaphore {
    public static void main(String[] args) {
        java.util.concurrent.Semaphore semaphore = new java.util.concurrent.Semaphore(3);
        for (int i = 0; i < 6; i++) {
            new Thread(()->{
                try {
                    semaphore.acquire();
                    System.out.println("线程:"+Thread.currentThread().getName()+"\t抢到车位!");
                    TimeUnit.SECONDS.sleep(3);
                    System.out.println("线程:"+Thread.currentThread().getName()+"\t占用3秒后离开车位!");
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    semaphore.release();
                }
            },String.valueOf(i)).start();
        }
    }
}

测试结果
在这里插入图片描述
参考文章
https://www.jianshu.com/p/333fd8faa56e
https://blog.csdn.net/u013851082/article/details/70208246

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值