【Redisson starter】 信号量 Semaphore

Metadata

title: 【Redisson starter】 信号量 Semaphore
date: 2023-01-22 21:49
tags:
  - 行动阶段/完成
  - 主题场景/组件
  - 笔记空间/KnowladgeSpace/ProgramSpace/ModuleSpace
  - 细化主题/Module/Redisson
categories:
  - Redisson
keywords:
  - Redisson
description: 【Redisson starter】 信号量 Semaphore 基于Redis的Redisson的分布式信号量(Semaphore)Java对象RSemaphore采用了与java.util.concurrent.Semaphore相似的接口和用法。同时还提供了异步(Async)、反射式(Reactive)和RxJava2标准的接口。

【Redisson starter】 信号量 Semaphore

基于Redis的Redisson的分布式信号量(Semaphore)Java对象RSemaphore采用了与java.util.concurrent.Semaphore相似的接口和用法。同时还提供了异步(Async)、反射式(Reactive)和RxJava2标准的接口。

 /**
     * 信号量
     * @param semaphoreName
     * @return
     */
    public RSemaphore getSemaphore(String semaphoreName) {
        return redissonClient.getSemaphore(semaphoreName);
    }
 /**
     * 信号量
     */
    @Test
    public void testSemaphore() throws InterruptedException {
        RSemaphore semaphore = redissonTemplate.getSemaphore("testSemaphore");
        //设置许可个数
        semaphore.trySetPermits(10);
//        //设置许可个数 异步
//        semaphore.acquireAsync();
//        //获取5个许可
//        semaphore.acquire(5);
//        //尝试获取一个许可
//        semaphore.tryAcquire();
//        //尝试获取一个许可 异步
//        semaphore.tryAcquireAsync();
//        //尝试获取一个许可 等待5秒如果未获取到,则返回false
//        semaphore.tryAcquire(5, TimeUnit.SECONDS);
//        //尝试获取一个许可 等待5秒如果未获取到,则返回false 异步
//        semaphore.tryAcquireAsync(5, TimeUnit.SECONDS);
//        //释放一个许可,将其返回给信号量
//        semaphore.release();
//        //释放 6 个许可 ,将其返回给信号量
//        semaphore.release(6);
//        //释放一个许可,将其返回给信号量 异步
//        semaphore.releaseAsync();

        CountDownLatch count = new CountDownLatch(10);
        for (int i= 0;i< 15 ;++i){
            new Thread(() -> {
                try {
                    String threadName = Thread.currentThread().getName();
                    log.info("线程:{} 尝试获取许可。。。。。。。。。。。。。",threadName);
                    //默认获取一个许可,如果没有获取到,则阻塞线程
                    semaphore.acquire();
                    log.info("线程:{}获取许可成功。。。。。。。", threadName);
                    count.countDown();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
        count.await();
    }

在实现信号量的时候一定要注意许可数量,如果被使用完,而你用完之后并没有将许可归还给信号量,那么有可能在许可用完之后,之后的线程一直处于阻塞阶段。

关于信号量还有一个:可过期性信号量(PermitExpirableSemaphore),获取到的许可有效期只有你设置的时长,

/**
     * 可过期性信号量
     * @param permitExpirableSemaphoreName
     * @return
     */
    public RPermitExpirableSemaphore  getPermitExpirableSemaphore(String permitExpirableSemaphoreName) {

        return redissonClient.getPermitExpirableSemaphore(permitExpirableSemaphoreName);
    }
/**
     * 信号量
     */
    @Test
    public void testPermitExpirableSemaphore() throws InterruptedException {
        RPermitExpirableSemaphore semaphore = redissonTemplate.getPermitExpirableSemaphore("testPermitExpirableSemaphore");
        //设置许可个数
        semaphore.trySetPermits(10);
        // 获取一个信号,有效期只有2秒钟。
        String permitId = semaphore.acquire(1, TimeUnit.SECONDS);
        log.info("许可:{}",permitId);
        semaphore.release(permitId);
    }