redis分布式锁工具类

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class RedisUtils {

    private static RedissonClient REDISSON_CLIENT;

    public RedisUtils(@Autowired RedissonClient redissonClient) {
        REDISSON_CLIENT = redissonClient;
    }

    /**
     * 尝试获取锁
     *
     * @param key 锁key
     * @param waitTime  最多等待时间,0:表示不等待,只尝试加锁一次
     * @param leaseTime 上锁后自动释放锁时间,-1:表示不自动释放锁
     * @return 获取锁成功返回true 失败返回false
     */
    public static boolean tryLock(String key, long waitTime, long leaseTime) {
        RLock lock = REDISSON_CLIENT.getLock(key);
        try {
            return lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            return false;
        }
    }

    public static void unlock(String key) {
        RLock lock = REDISSON_CLIENT.getLock(key);
        if (lock.isLocked() && lock.isHeldByCurrentThread()) {
            lock.unlock();
        } else {
            log.warn("redis锁已超时释放");
        }
    }

}

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class RedisUtils {

    private static RedissonClient REDISSON_CLIENT;

    public RedisUtils(@Autowired RedissonClient redissonClient) {
        REDISSON_CLIENT = redissonClient;
    }

    /**
     * 尝试获取锁
     *
     * @param key 锁key
     * @param waitTime  最多等待时间,0:表示不等待,只尝试加锁一次
     * @param leaseTime 上锁后自动释放锁时间,-1:表示不自动释放锁
     * @return 获取锁成功返回true 失败返回false
     */
    public static boolean tryLock(String key, long waitTime, long leaseTime) {
        RLock lock = REDISSON_CLIENT.getLock(key);
        try {
            return lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            return false;
        }
    }

    public static void unlock(String key) {
        RLock lock = REDISSON_CLIENT.getLock(key);
        if (lock.isLocked() && lock.isHeldByCurrentThread()) {
            lock.unlock();
        } else {
            log.warn("redis锁已超时释放");
        }
    }

}

定时任务的制作示例

import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
@Slf4j
public class ScheduledTasks {

    @Resource
    private DynamicConfig dynamicConfig;

    @Resource
    private IQwUserService qwUserService;

    /**
     * 初始化企微用户信息
     * fixedRate 每隔固定时间执行一次
     */
    @Scheduled(fixedRate = 30*60*1000)
    @Async("commonExecutor") // 用线程池执行,防止互相影响,因为@Scheduled任务是单线程执行的
    public void initQwUser() {
        MDC.put(CommonConstant.REQUEST_ID, UuidUtils.getUUID());
        log.info("定时任务【initQwUser】开始执行...");
        // 是否初始化企微用户信息
        if (dynamicConfig.getIsInitQwUser()) {
            String lockKey = CommonConstant.INIT_QW_USER_LOCK_KEY;
            // 只加一次锁,获取不到证明已经有一个任务获取到了
            if (RedisUtils.tryLock(lockKey, 0, 60 * 25)) {
                try {
                    log.info("分布式锁加锁成功, lockKey = {}", lockKey);
                    qwUserService.sync(null);
                } finally {
                    RedisUtils.unlock(lockKey);
                    log.info("分布式锁释放成功, lockKey = {}", lockKey);
                }
            } else {
                log.info("未获取到分布式锁");
            }
        } else {
            log.info("未开启初始化企微用户信息");
        }
        log.info("定时任务【initQwUser】执行完毕...");
    }

}

import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
@Slf4j
public class ScheduledTasks {

    @Resource
    private DynamicConfig dynamicConfig;

    @Resource
    private IQwUserService qwUserService;

    /**
     * 初始化企微用户信息
     * fixedRate 每隔固定时间执行一次
     */
    @Scheduled(fixedRate = 30*60*1000)
    @Async("commonExecutor") // 用线程池执行,防止互相影响,因为@Scheduled任务是单线程执行的
    public void initQwUser() {
        MDC.put(CommonConstant.REQUEST_ID, UuidUtils.getUUID());
        log.info("定时任务【initQwUser】开始执行...");
        // 是否初始化企微用户信息
        if (dynamicConfig.getIsInitQwUser()) {
            String lockKey = CommonConstant.INIT_QW_USER_LOCK_KEY;
            // 只加一次锁,获取不到证明已经有一个任务获取到了
            if (RedisUtils.tryLock(lockKey, 0, 60 * 25)) {
                try {
                    log.info("分布式锁加锁成功, lockKey = {}", lockKey);
                    qwUserService.sync(null);
                } finally {
                    RedisUtils.unlock(lockKey);
                    log.info("分布式锁释放成功, lockKey = {}", lockKey);
                }
            } else {
                log.info("未获取到分布式锁");
            }
        } else {
            log.info("未开启初始化企微用户信息");
        }
        log.info("定时任务【initQwUser】执行完毕...");
    }

}

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐