同步工具类 CountDownLatch、CyclicBarrier、Semaphore的用法
发布日期:2022-02-01 14:28:22 浏览次数:38 分类:技术文章

本文共 4144 字,大约阅读时间需要 13 分钟。

1.CountDownLatch类

CountDownLatch(闭锁)是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待,在构造方法中指定一组线程的数量,等待其完成后再继续执行。

构造方法:CountDownLatch  cd=new  CountDownLatch( 5);//指定组为5个线程。

闭锁可以延迟线程的进度直到其到达终止状态,闭锁可以用来确保某些活动直到其他活动都完成才能继续执行:

(1)确保某个计算在其需要的所有资源都被初始化后才能继续执行。
(2)确保某个服务在其依赖的所有其他服务都已经启动之后才启动。
(3)等待直到某个操作所有参与者都执行完毕其他线程才能继续执行。

案例分析:所有员工都到达,老板开始开始开会

//老板线程类public class Boss implements Runnable{    private CountDownLatch countDownLatch;    public Boss(CountDownLatch countDownLatch) {        this.countDownLatch = countDownLatch;    }    @Override    public void run() {        System.out.println("老板等员工来齐");        try {            countDownLatch.await();        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("人来完了,开始开会...");    }}//员工线程类public class Employee implements Runnable{    private CountDownLatch countDownLatch;    public Employee(CountDownLatch countDownLatch) {        this.countDownLatch = countDownLatch;    }    @Override    public void run() {        System.out.println(Thread.currentThread().getName()+"来到了会议室999...");        countDownLatch.countDown();//每次执行完一个线程之后等待的组中线程数就减一,减完后等待线程就执行    }}//测试public class CountDownLacthTest {    public static void main(String[] args) {        CountDownLatch countDownLatch=new CountDownLatch(5);//五个员工        Boss boss=new Boss(countDownLatch);        Employee employee=new Employee(countDownLatch);        new Thread(boss).start();        for (int i = 1; i <5 ; i++) {            try {                Thread.sleep(2000);            } catch (InterruptedException e) {                e.printStackTrace();            }            new Thread(employee).start();//创建多个员工线程        }    }}

2.CyclicBarrier类

CyclicBarrier和CountDownLatch类似(屏障)表面意思理解为可循环使用的屏障,作用是让一组线程在到达一个屏障时被阻塞,等到最后一个线程到达屏障点,才会运行被拦截的线程继续运行。

(1)构造函数 CyclicBarrier(int parties) 屏障拦截的线程数量
(2)await() 调用该方法时表示线程已经到达屏障,随即阻塞

案例:等待所有运动员都到位才开始赛跑

运动员线程类;public class SportMan implements Runnable{    private CyclicBarrier cyclicBarrier;    public SportMan(CyclicBarrier cyclicBarrier) {        this.cyclicBarrier = cyclicBarrier;    }    @Override    public void run() {        System.out.println(Thread.currentThread().getName()+"运动员准备号了。。。");        try {            cyclicBarrier.await();        } catch (InterruptedException e) {            e.printStackTrace();        } catch (BrokenBarrierException e) {            e.printStackTrace();        }        try {            Thread.sleep(2000);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println(Thread.currentThread().getName()+"比赛结束");    }}测试:public class Demo {    public static void main(String[] args) {        CyclicBarrier cyclicBarrier =new CyclicBarrier(6, new Runnable() {            @Override            public void run() {                System.out.println("开始比赛");            }        });        SportMan sportMan=new SportMan(cyclicBarrier);        for (int i = 0; i <10 ; i++) {            new Thread(sportMan).start();        }    }}

3.Semaphore类

Semaphore 是 synchronized 的加强版,作用是控制线程的并发数量。就这一点而言,单纯的synchronized 关键字是实现不了的。

 用来控制同时访问特定资源的线程数量,通过协调保证合理的使用公共资源。
 比作控制车流的红绿灯,如马路要控制流量,只限制100辆车通行,其他必须在路口处等待,不能行驶在马路上,当其中有5辆离开马路,那么允许后面5辆进入马路。
案例:

//创建线程类public class MyThread extends Thread{    private Semaphore semaphore;    public MyThread(Semaphore semaphore) {        this.semaphore = semaphore;    }    @Override    public void run() {        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");        try {            try {                semaphore.acquire();//获取锁                System.out.println(Thread.currentThread().getName()+"开始执行...");                Thread.sleep(2000);            } catch (InterruptedException e) {                e.printStackTrace();            }        } finally {            semaphore.release();//释放锁            System.out.println(Thread.currentThread().getName()+"执行结束...");        }    }}//测试:public class SemaphoreDemo {    public static void main(String[] args) {        Semaphore semaphore=new Semaphore(3);//指定三个线程同时执行        for (int i = 0; i <10 ; i++) {            new MyThread(semaphore).start();        }    }}

转载地址:https://blog.csdn.net/shunshizhen120412/article/details/99606020 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:asp产生随机数
下一篇:Channel通道进行读写操作和文件的复制等操作

发表评论

最新留言

逛到本站,mark一下
[***.202.152.39]2024年04月14日 11时59分50秒