Redission 可重入锁(Reentrant Lock)公平锁(Fair Lock)

  1. 可重入锁(Reentrant Lock)
    Redisson的分布式可重入锁RLock Java对象实现了java.util.concurrent.locks.Lock接口,同时还支持自动过期解锁。
public void testReentrantLock(RedissonClient redisson){
    
    

        RLock lock = redisson.getLock("anyLock");
        try{
    
    
            // 1. 最常见的使用方法
            //lock.lock();

            // 2. 支持过期解锁功能,10秒钟以后自动解锁, 无需调用unlock方法手动解锁
            //lock.lock(10, TimeUnit.SECONDS);

            // 3. 尝试加锁,最多等待3秒,上锁以后10秒自动解锁
            boolean res = lock.tryLock(3, 10, TimeUnit.SECONDS);
            if(res){
    
        //成功
                // do your business

            }
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            lock.unlock();
        }

    }

Redisson同时还为分布式锁提供了异步执行的相关方法:

public void testAsyncReentrantLock(RedissonClient redisson){
    
    
        RLock lock = redisson.getLock("anyLock");
        try{
    
    
            lock.lockAsync();
            lock.lockAsync(10, TimeUnit.SECONDS);
            Future<Boolean> res = lock.tryLockAsync(3, 10, TimeUnit.SECONDS);

            if(res.get()){
    
    
                // do your business

            }
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        } catch (ExecutionException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            lock.unlock();
        }

    }
  1. 公平锁(Fair Lock)
    Redisson分布式可重入公平锁也是实现了java.util.concurrent.locks.Lock接口的一种RLock对象。在提供了自动过期解锁功能的同时,保证了当多个Redisson客户端线程同时请求加锁时,优先分配给先发出请求的线程。
public void testFairLock(RedissonClient redisson){
    
    

        RLock fairLock = redisson.getFairLock("anyLock");
        try{
    
    
            // 最常见的使用方法
            fairLock.lock();

            // 支持过期解锁功能, 10秒钟以后自动解锁,无需调用unlock方法手动解锁
            fairLock.lock(10, TimeUnit.SECONDS);

            // 尝试加锁,最多等待100秒,上锁以后10秒自动解锁
            boolean res = fairLock.tryLock(100, 10, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            fairLock.unlock();
        }

    }

Redisson同时还为分布式可重入公平锁提供了异步执行的相关方法:

RLock fairLock = redisson.getFairLock("anyLock");
fairLock.lockAsync();
fairLock.lockAsync(10, TimeUnit.SECONDS);
Future<Boolean> res = fairLock.tryLockAsync(100, 10, TimeUnit.SECONDS);
/*
 * Copyright 2021 Wicrenet, Inc. All rights reserved.
 */
package com.allianity.modules.cms.cache.impl;

import com.allianity.common.learning.enums.RedisRouteKeyEnum;
import com.allianity.modules.cms.cache.UserCoursewareCache;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.LongCodec;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 【】
 *
 * @author yangjunxiong
 * Created on 2021/1/14 11:42
 */
@Component
public class UserCoursewareCacheImpl implements UserCoursewareCache {
    
    

    @Autowired
    private RedissonClient redissonClient;

    @Override
    public Boolean setUserCoursewareDuration(Long userId, Long s) {
    
    
        if (Objects.isNull(userId) || Objects.isNull(s)) {
    
    
            return false;
        }
        RMapCache<String, Long> mapCache = redissonClient.getMapCache(RedisRouteKeyEnum.T_USER_COURSEWARE_DURATION.getKey(), LongCodec.INSTANCE);
        mapCache.addAndGet(userId + "", s);
        mapCache.expire(RedisRouteKeyEnum.ACTIVITY_AUDIENCE_INFO.getTTL0(), TimeUnit.SECONDS);
        return true;
    }

    @Override
    public Long getUserCoursewareDuration(Long userId) {
    
    
        RMapCache<String, Long> mapCache = redissonClient.getMapCache(RedisRouteKeyEnum.T_USER_COURSEWARE_DURATION.getKey(), LongCodec.INSTANCE);
        return mapCache.get(userId + "");
    }
}

/*
 * Copyright 2020 Wicrenet, Inc. All rights reserved.
 */
package com.allianity.modules.report.cache;

import com.allianity.common.learning.enums.RedisRouteKeyEnum;
import com.allianity.modules.report.controller.model.CourseGroupRateReportQuery;
import com.allianity.modules.report.dto.CourseGroupRateBycgIdDTO;
import com.allianity.modules.report.dto.CourseGroupRateReportByDeptIdDTO;
import com.allianity.modules.report.dto.ReportUserDto;
import com.allianity.modules.report.service.impl.AbsCourseGroupRateReportServiceImpl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.joda.time.LocalDateTime;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * 【 任务完成率 缓存层 】
 *
 * @author YJX
 * Created on 2020/12/7 18:02
 */

@Primary
@Service
@Qualifier("cache")
public class CourseGroupRateReportCacheServiceImpl extends AbsCourseGroupRateReportServiceImpl {
    
    

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    @Qualifier("base")
    private AbsCourseGroupRateReportServiceImpl absCourseGroupRateReportService;

    @Override
    public Page<CourseGroupRateReportByDeptIdDTO> pageingByDeptId(CourseGroupRateReportQuery query) {
    
    
        RBucket<Page<CourseGroupRateReportByDeptIdDTO>> bucket = redissonClient.getBucket(RedisRouteKeyEnum.API_REPORT_COURSE_GROUP_RATE.getKey() + ":" + query.getStatisticsType() + ":" + query.getDeptId() + ":" + query.getPage() + ":" + query.getLimit() +":" + LocalDateTime.now().toString("yyyy-M-d"));
        Page<CourseGroupRateReportByDeptIdDTO> page = bucket.get();
        if (Objects.isNull(page)) {
    
    
            page = this.absCourseGroupRateReportService.pageingByDeptId(query);
            bucket.set(page);
            bucket.expire(RedisRouteKeyEnum.API_REPORT_COURSE_GROUP_RATE.getTimeToLive(), TimeUnit.SECONDS);
        }
        return page;
    }
}

    private synchronized Boolean checkNub(String actId, String treeId) {
    
    
        TreeSaplingEntity one = this.treeSaplingService.getOne(new LambdaQueryWrapper<TreeSaplingEntity>()
                .eq(TreeSaplingEntity::getActId, actId)
                .eq(TreeSaplingEntity::getTreeId, treeId)
                .eq(TreeSaplingEntity::getDelFlag, 0)
                .eq(TreeSaplingEntity::getStatus, 1)//是否有效
        );
        //可领取总数
        Integer treeTotalNumber = one.getTreeTotalNumber();
        //redis处理超领事件
        RAtomicLong atomicLong = redissonClient.getAtomicLong(RedisRouteKeyEnum.TREE_ACTIVITY_TREE_ID_COUNT.getKey() + actId + "_" + treeId);
        long sum = atomicLong.get();
        if (sum == 0L) {
    
    
            //已领取数量
            sum = this.count(new LambdaQueryWrapper<TreeUserEntity>()
                    .eq(TreeUserEntity::getActId, actId)
                    .eq(TreeUserEntity::getTreeId, treeId)
                    .eq(TreeUserEntity::getDelFlag, 0)
            );
            atomicLong.expire(RedisRouteKeyEnum.TREE_ACTIVITY_TREE_ID_COUNT.getTimeToLive(), TimeUnit.SECONDS);
        }
        Boolean a = sum < treeTotalNumber;
        if (a) {
    
    
            //自增加1
            sum = atomicLong.incrementAndGet();
        }
        return a;
    }

猜你喜欢

转载自blog.csdn.net/qq_40250122/article/details/112604331