java在定时任务中使用redis分布式锁

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】执行完毕...");
    }

}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奋力向前123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值