Redisson PermitExpirableSemaphore源码详解

这两天的工作中发现了一个问题。原本一直在使用的redisson提供的semaphore信号量经常会莫名其妙的消失,也就是所谓的信号量泄露,发现问题出在调用的外部服务上,所以我只能试图通过给semaphore的每个信号量设置过期时间,也就是说当获取一个信号量的时候,如果在一定时间内没有归还,那么信号量将自动归还在总值里。这个时候就要使用redisson提供的另外一个功能,PermitExpirableSemaphore,他提供了为每个信号量设置过期时间的功能。...
摘要由CSDN通过智能技术生成

Redisson PermitExpirableSemaphore源码详解

这两天的工作中发现了一个问题。原本一直在使用的redisson提供的semaphore信号量经常会莫名其妙的消失,也就是所谓的信号量泄露,发现问题出在调用的外部服务上,所以我只能试图通过给semaphore的每个信号量设置过期时间,也就是说当获取一个信号量的时候,如果在一定时间内没有归还,那么信号量将自动归还在总值里。

这个时候就要使用redisson提供的另外一个功能,PermitExpirableSemaphore,他提供了为每个信号量设置过期时间的功能。

但是其实阅读一个成熟框架的源码是十分痛苦并且困难的,所以我努力对这个功能里涉及的源码都进行了一些简单的注释。

PermitExpirableSemaphore几个需要注意的点。

1.PermitExpirableSemaphore并不想Semaphore一样能直观的看到剩余多少信号量。他通过维护一个zset类型来记录你目前使用的信号量,该zest中的score被设置为过期的时间,并通过判断zset中的score是否过期以及你的PermitExpirableSemaphore对象中剩余的信号量数值进行判断。

2.上一条中提到的zset中的数据并不会随着信号过期而被自动删除,会一直留存中zset中,当新的信号量进来时,会对zset中最早过期的信号量进行替换。

下面的代码是一个简单的示例。有关于tryAcquire方法的,也就是尝试获取信号量。

然后我会一层一层点进源码并添加注释来帮助大家理解。

@Slf4j
@Service
public class RedissonTestServiceImpl implements RedissonTestService{
   
    @Autowired
    private RedissonClient redissonClient;
    @Override
    public void test() {
   
        RPermitExpirableSemaphore test2 = redissonClient.getPermitExpirableSemaphore("test2");
        try {
   
//            String acquire = test2.acquire(10, TimeUnit.MILLISECONDS);
            String acquire = test2.tryAcquire(0,100,TimeUnit.SECONDS);
            System.out.println(acquire);
//            Thread.sleep(5000);
        } catch (InterruptedException e) {
   
            e.printStackTrace();
        }
    }
}

点进tryAcquire(0,100,TimeUnit.SECONDS);这个方法中

public interface RPermitExpirableSemaphore extends RExpirable, RPermitExpirableSemaphoreAsync {
   
    String acquire() throws InterruptedException;

    String acquire(long var1, TimeUnit var3) throws InterruptedException;

    String tryAcquire();

    String tryAcquire(long var1, TimeUnit var3) throws InterruptedException;

    //进入这一行 var1为等待(自旋)获取信号量的时间  waittime
    //var3 为你给这个信号量设置的过期时间 ttl
    //var5 时间的单位 例如 TimeUnit.SECONDS
    String tryAcquire(long var1, long var3, TimeUnit var5) throws InterruptedException;

    boolean tryRelease(String var1);

    void release(String var1);

    int availablePermits();

    boolean trySetPermits(int var1);

    void addPermits(int var1);

    boolean updateLeaseTime(String var1, long var2, TimeUnit var4);
}

点进去

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值