10、常用的辅助类

10.1、CountDownLatch(计数器)

在这里插入图片描述
官方文档中,对这一块的解释比较复杂,简单来说,该类就是一个减法计数器,一般用于计算线程的执行次数,当达到0时执行某一操作。

举个例子,假设现在一个班上有6名学生,现在放学了,老师要关教室门,就必须要等6名同学全部走完才能关门,因此,每走一个学生,就对剩下的学生总数-1,直到所有学生都走完,老师才能关教室门。

我们来实现这个案例:

public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        //定义计数器,计数6次
        CountDownLatch countDownLatch = new CountDownLatch(6);
        for (int i = 1; i < 7; i++) {
            new Thread(()-> {
                System.out.println(Thread.currentThread().getName()+"号学生出教室");
                countDownLatch.countDown(); //每次走出一个学生,计数器-1
            },String.valueOf(i)).start();
        }
        countDownLatch.await();     //当计数器归0时执行后面的程序
        System.out.println("老师关门");
    }
}

运行结果:
在这里插入图片描述
由此,我们就完成了这个案例,可以看出,CountDownLatch的作用就是帮我们记录线程的执行次数,每运行一条线程,调用了countDown() 方法,就进行一次-1计数,当计数为0时,就唤醒await()方法去执行后面的代码;不为0就会一直阻塞。

在CountDownLatch中,我们主要记住这两个方法即可:
  • countDown(); 计数-1
  • await(); 等待计数归0,然后再向下执行

10.2、CyclicBarrier

在这里插入图片描述
同样与CountDownLatch,官方对这一块的解释也十分抽象。其实简单来说,这就是一个加法计数器,毕竟计数有了减法,就一定有加法。
在这里插入图片描述
可以看到,在创建CyclicBarrier对象时,有两个构造的重载,第一个重载有两个参数分别代表的意思是int:记录线程的次数Runnable:达到次数后执行的线程

我们用一个案例来表示:

假设现在有7个人准备一起吃饭,而服务员要等7个人到齐了才会上菜

代码实现
public class CyclicBarrierDemo {
    public static void main(String[] args) {

        CyclicBarrier barrier = new CyclicBarrier(7, () -> {
            System.out.println("服务员上菜");
        });
        for (int i = 1; i <= 7; i++) {
            new Thread(()->{
                System.out.println(Thread.currentThread().getName()+"客人到了");
                try {
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            },String.valueOf(i)).start();
        }
    }
}

运行结果
在这里插入图片描述
可以看到,每次运行一条线程,线程就会进行等待并+1,直到7条线程全部执行,就会唤醒我们在创建对象中传递的服务员线程进行执行;

10.3、Semaphore(信号量)

在这里插入图片描述
简单来讲,Semaphore就是为限制线程个数而生的;举个简单的例子,现在有6辆车,但是停车场只有3个车位,因此必定会有3辆车在外面等候有空余车位时才能停车。当其中的一辆或多辆车准备离开时,就释放了停车的空间,其他车就可以进来停车。

案例实现:

public class SemaphoreDemo {
    public static void main(String[] args) {
        //设置3个车位
        Semaphore semaphore = new Semaphore(3);

        //创建6条线程,模拟6辆车
        for (int i = 1; i <= 6; i++) {
            new Thread(()->{
                try {
                    semaphore.acquire();    //占用资源
                    System.out.println(Thread.currentThread().getName()+"号车停车,占用车位");
                    TimeUnit.SECONDS.sleep(2);  //设置延迟,模拟占用车位
                    System.out.println(Thread.currentThread().getName()+"号车已离开");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();    //释放资源
                }
            },String.valueOf(i)).start();
        }
    }
}

运行结果
在这里插入图片描述
可以看到,使用Semaphore可以对线程数的控制;

  • acquire(); 获取资源,该方法会阻塞,直到有资源可用,才能使用它
  • release(); 释放资源。

使用该类进行线程控制,能够实现一种限流的操作,控制最大线程数,可以保证服务器硬件资源的安全。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值