(三)并发工具类Semaphore(真正的限流器)

Semaphore信号量是一种并发控制工具,不同于CountDownLatch和CyclicBarrier,它适用于线程限流场景。Semaphore通过init()初始化计数器,down()减少计数器并可能阻塞线程,up()增加计数器并唤醒等待线程。Java示例中展示了如何使用Semaphore进行资源互斥访问,限制同时执行的线程数量。
摘要由CSDN通过智能技术生成

Semaphore(限流)

概述

CountDownLatch(门闩)与CyclicBarrier(栅栏)看似需要等待线程数达到相同的数量才能继续执行,但它们并不能作为限流器使用,例如实现一个车辆限流,小于10辆直接通行,大于10辆则等待。CountDownLatch(门闩)与CyclicBarrier(栅栏)在小10辆时也无法通行,因此不适合作为限流器使用。Semaphore信号量主要用于两个目的,一个是用于多个共享资源的互斥使用,另一个用于并发线程数的控制。

信号量模型

信号量模型还是很简单的,可以简单概括为:一个计数器,一个等待队列,三个方法。在信号量模型里,计数器和等待队列对外是透明的,所以只能通过信号量模型提供的三个方法来访问它们,这三个方法分别是:init()、down() 和 up()。你可以结合下图来形象化地理解。
在这里插入图片描述
这三个方法详细的语义具体如下所示。
init():设置计数器的初始值。
down():计数器的值减 1;如果此时计数器的值小于 0,则当前线程将被阻塞,否则当前线程可以继续执行。
up():计数器的值加 1;如果此时计数器的值小于或者等于 0,则唤醒等待队列中的一个线程,并将其从等待队列中移除。


使用方法

下面是 Java 代码的示例,acquire() 就是信号量里的 down() 操作,release() 就是信号量里的 up() 操作。

static int count;
//初始化信号量
static final Semaphore s 
    = new Semaphore(1);
//用信号量保证互斥    
static void addOne() {
  s.acquire();
  try {
    count+=1;
  } finally {
    s.release();
  }
}

拓展实际应用:

public class T11_TestSemaphore {
    static Semaphore semaphore = new Semaphore(2);
    public static void main(String[] args){
        new Thread(()->{
            try {
                semaphore.acquire();
                System.out.println("1开始");
                Thread.sleep(100);
                semaphore.release();
                System.out.println("1结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        new Thread(()->{
            try {
                semaphore.acquire();
                System.out.println("2开始");
                Thread.sleep(100);
                semaphore.release();
                System.out.println("2结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值