ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

说说CountDownLatch/CyclicBarrier/Semaphore的使用

2022-01-13 18:59:24  阅读:173  来源: 互联网

标签:号车 三秒 String int Semaphore 线程 CountDownLatch CyclicBarrier public


1、CountDownLatch

  • 让一些线程阻塞直到另外一些完成后才被唤醒
    • CountDownLatch主要有两个方法,当一个或有多个线程调用await方法时,调用的线程会被阻塞.其他线程调用countDown方法计数器减1(调用countDown方法时线程不会阻塞)
    • 当计数器的值变为0,因调用await方法而被阻塞的线程会被唤醒,然后继续执行该线程的操作
package com.song.CountDownLatchTest;
import java.util.concurrent.CountDownLatch;
/**
 *场景案例: 秦始皇统一六国 当六国全部被灭了 才实现了统一
 */
public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(6);//要等待的工作线程的个数--》这里设置为六个
        for (int i = 1; i <= 6; i++) {
            new Thread(()->{
               System.out.println(Thread.currentThread().getName()+"\t被灭");
               countDownLatch.countDown();//执行一次就减一次  countDown方法计数器减1(调用countDown方法时线程不会阻塞)
            },CountryEnum.getCountryEnum(i).getMessage()).start();//CountryEnum使用的枚举
        }
        countDownLatch.await();//当计数器的值减为0时,调用await方法被阻塞的线程(这里阻塞的线程是main)会被唤醒,继续执行
        System.out.println("秦始皇一统天下");
    }
}
//自定的枚举类
public enum  CountryEnum {
    ONE(1,"齐国"),TWO(2,"韩国"),THREE(3,"赵国"),FOUR(4,"楚国"),FIVE(5,"燕国"),SIX(6,"魏国");
    private int reCode;
    private String message;

    CountryEnum(int reCode, String message) {
        this.reCode = reCode;
        this.message = message;
    }

    public static CountryEnum getCountryEnum(int i){
        CountryEnum[] values = CountryEnum.values();
        for (CountryEnum countryEnum : values) {
            if (countryEnum.getReCode() == i) {
                return countryEnum;
            }
        }
        return null;
    }
   
    public int getReCode() {
        return reCode;
    }

    public void setReCode(int reCode) {
        this.reCode = reCode;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

###输出随机结果
齐国	被灭
燕国	被灭
魏国	被灭
楚国	被灭
韩国	被灭
赵国	被灭
秦始皇一统天下

Process finished with exit code 0

2、CyclicBarrier

  • CyclicBarrier的字面意思是可循环(Cyclic) 使用的屏障(barrier)
    • 它要做的事情是,让一组线程到达一个屏障(也可以叫做同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活,线程进入屏障通过CyclicBarrier的await()方法.
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 *场景案例:集齐七龙珠召唤神龙
 */
public class CyclicBarrierDemo {
    public static void main(String[] args) {
        //其参数表示屏障拦截的线程数量 ----》这里拦截数量为7
        CyclicBarrier cyclicBarrier=new CyclicBarrier(7,()->{
            System.out.println("召唤神龙");
        });

        //当以下线程全部到达屏障(都参与线程调用了await方法)时 才会执行后续操作
        for (int i = 1; i <=7; i++) {
            final int temp = i;
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"\t 收集到第"+ temp +"颗龙珠");
                try {
                    //告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。
                    cyclicBarrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}
###输出的随机结果
3	 收集到第3颗龙珠
5	 收集到第5颗龙珠
1	 收集到第1颗龙珠
2	 收集到第2颗龙珠
6	 收集到第6颗龙珠
4	 收集到第4颗龙珠
7	 收集到第7颗龙珠
召唤神龙

Process finished with exit code 0

3、Semaphore

  • 是一个线程同步的辅助类,可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore(信号量)的主要两个目的,一个是用于多个共享资源的相互排斥使用,另一个用于并发资源数的控制.
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 *
 *场景模拟:停车场停车 总共有3个车位 6俩车去停 每个车停三秒开走
 */
public class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(3);//模拟3个停车位
        for (int i = 1; i <= 6; i++) {
            new Thread(()->{
                try {
                    //抢到资源
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+"\t 号车抢到了停车位");
                    try { 
                        TimeUnit.SECONDS.sleep(3);
                    } catch (InterruptedException e) { 
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"\t 号车停了三秒走了");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    //释放资源
                    semaphore.release();
                }
            },String.valueOf(i)).start();
        }
    }
}
###输出的随机结果
1	 号车抢到了停车位
3	 号车抢到了停车位
2	 号车抢到了停车位
2	 号车停了三秒走了
3	 号车停了三秒走了
4	 号车抢到了停车位
1	 号车停了三秒走了
5	 号车抢到了停车位
6	 号车抢到了停车位
6	 号车停了三秒走了
4	 号车停了三秒走了
5	 号车停了三秒走了

Process finished with exit code 0

标签:号车,三秒,String,int,Semaphore,线程,CountDownLatch,CyclicBarrier,public
来源: https://blog.csdn.net/qq_44763720/article/details/122480307

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有