多线程系列学习:CountDownLatch、CyclicBarrier和Semaphore

之所以把这3个类放在一起,因为它们都是线程协作的辅助类。

  1. CountDownLatch,可以实现某一些线程,等待其他线程执行完之后,才可以执行
  2. CyclicBarrier,实现了多个线程间的相互等待,直到大家等待的条件满足了,就可以一起执行了
  3. Semaphore,是信号量,可以控制并发的线程数

一、CountDownLatch

CountDownLatch,更多的是用于等待前面的线程执行完了,后面的才可以执行,测试如下:

public class CountDownLatchTest {
    public static void main(String[] args) {
        int count = 3;
        CountDownLatch latch = new CountDownLatch(3);
        for (int i = 0; i < count; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName()+" is run,System.currentTimeMillis() = "+System.currentTimeMillis());
                try {
                    Thread.sleep(1000);
                    // 计数减1
                    latch.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
        // 等待3个线程执行完成,才执行下面的任务
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(count+ " 个线程的都执行完了,该我执行了,System.currentTimeMillis() = "+System.currentTimeMillis());
    }
}

测试结果:

Thread-0 is run,System.currentTimeMillis() = 1616429063878
Thread-1 is run,System.currentTimeMillis() = 1616429063878
Thread-2 is run,System.currentTimeMillis() = 1616429063878
3 个线程的都执行完了,该我执行了,System.currentTimeMillis() = 1616429064880

首先,count = 3,启动了3个线程,在每个线程执行完了之后,执行如下方法,进行计数器减1:

countDown();

而它的await()方法,会阻塞,直到计数从3减到0,才会继续执行后面的代码,所以3个子线程执行完了,才会继续执行主线程的代码。

 

二、CyclicBarrier

 CyclicBarrier的作用,可以用来实现多个线程的相互等待,直到满足等待条件,你可以想象这个过程:跑步的时候,只有等大家各就各位做好准备之后,听了枪声才会一起跑。而CyclicBarrier的作用就是让确定数目的几个人准备好了,让它们一起跑,不能一个先跑,另外一个后跑。

测试代码:

public class CyclicBarrierTest {
    public static void main(String[] args) {
        int count = 3;
        CyclicBarrier barrier = new CyclicBarrier(count);
        for (int i = 0; i < count; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName()+"开始执行,System.currentTimeMillis() = "+System.currentTimeMillis());
                try {
                    barrier.await();
                    System.out.println(Thread.currentThread().getName()+"等待结束,一起执行,System.currentTimeMillis() = "+System.currentTimeMillis());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

测试结果:

Thread-0开始执行,System.currentTimeMillis() = 1616428984532
Thread-2开始执行,System.currentTimeMillis() = 1616428984532
Thread-1开始执行,System.currentTimeMillis() = 1616428984532
Thread-1等待结束,一起执行,System.currentTimeMillis() = 1616428984532
Thread-2等待结束,一起执行,System.currentTimeMillis() = 1616428984532
Thread-0等待结束,一起执行,System.currentTimeMillis() = 1616428984532

可以看到,count = 3,只有await()的线程数量为3时,才会继续执行各自后面的代码。

 

三、Semaphore

Semaphore是通过许可的数量来控制可以执行的线程数的,请看测试代码:

public class SemaphoreTest {
    public static void main(String[] args) {
        int permits = 2;
        Semaphore semaphore = new Semaphore(permits);
        for (int i = 0; i <10 ; i++) {
            new Thread(() -> {
                // 获取许可
                try {
                    System.out.println(Thread.currentThread().getName()+",尝试获取许可");
                    semaphore.acquire();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 执行业务代码
                System.out.println(Thread.currentThread().getName()+",成功");
                // 释放许可
                semaphore.release();
            }).start();
        }
    }
}

 测试结果:

Thread-1,尝试获取许可
Thread-0,尝试获取许可
Thread-1,成功
Thread-2,尝试获取许可
Thread-0,成功
Thread-2,成功
Thread-3,尝试获取许可
Thread-3,成功
Thread-5,尝试获取许可
Thread-5,成功
Thread-4,尝试获取许可
Thread-4,成功
Thread-6,尝试获取许可
Thread-6,成功
Thread-9,尝试获取许可
Thread-9,成功
Thread-7,尝试获取许可
Thread-7,成功
Thread-8,尝试获取许可
Thread-8,成功

因为permits =2,说明同时只能有2个线程执行,如果把permits 改为1,那么它就只能是单线程的执行的,效果如下:

Thread-0,尝试获取许可
Thread-0,成功
Thread-1,尝试获取许可
Thread-1,成功
Thread-2,尝试获取许可
Thread-2,成功
Thread-3,尝试获取许可
Thread-3,成功
Thread-4,尝试获取许可
Thread-4,成功
Thread-5,尝试获取许可
Thread-5,成功
Thread-8,尝试获取许可
Thread-8,成功
Thread-9,尝试获取许可
Thread-9,成功
Thread-6,尝试获取许可
Thread-6,成功
Thread-7,尝试获取许可
Thread-7,成功

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值