java线程-如何通过信号量实现限流

信号量(Semaphore)是 Java 多线程并发中的一种 JDK 内置同步器,通过它可以实现多线程对公共资源的并发访问控制。

信号量由来

限流器

信号量的主要应用场景是控制最多 N 个线程同时地访问资源,其中计数器的最大值即是许可的最大值 N。

现在我们需要开发一个限流器,同一时刻最多有10个请求可以执行。对于这样的需求,我们实现的方案有:

  1. 使用Atomic类
  2. 使用Lock
  3. 使用条件变量
  4. 使用信号量

使用Atomic类实现

java复制代码public class LimitByAtomic {

  private static final AtomicInteger COUNTER = new AtomicInteger(10);

  public void f() {
    int count = COUNTER.decrementAndGet();
    if (count < 0) {
      COUNTER.incrementAndGet();
      System.out.println("拒绝执行业务逻辑");
      return; // 拒绝执行业务逻辑
    }

    try {
      // 执行业务逻辑
      System.out.println("执行业务逻辑");
    } finally {
      COUNTER.incrementAndGet();
    }
  }
}

使用Lock实现

java复制代码public class LimitByLock {

  private int count = 10;

  public void f() {
    if (count <= 0) {
      System.out.println("拒绝执行业务逻辑");
      return;
    }

    synchronized (this) {
      if (count <= 0) {
        System.out.println("拒绝执行业务逻辑");
        return;
      }
      count--;
    }

    try {
      // 执行业务逻辑
      System.out.println("执行业务逻辑");
    } finally {
      synchronized (this) {
        count++;
      }
    }
  }
}

使用条件变量实现

对于使用Atomic类还是Lock这两种实现方式,都有一个缺点,如果10个线程同时执行,当第11个线程来执行的时候,会被拒绝掉,这样就没有执行业务逻辑的机会,造成请求丢失。

所以我们可以通过线程等待-通知机制来解决上面的问题。如果10个线程同时执行,当第11个线程来执行的时候,先阻塞这第11个线程,等待前面的10个线程只要执行完一个,就通知第11个线程来执行。

java复制代码public class LimitByCondition {

  private int count = 10;

  public void f() throws Exception {
    synchronized (this) {
      while (count <= 0) {
        System.out.pri
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值