开发者

java如何使用redis加锁

开发者 https://www.devze.com 2023-01-10 10:33 出处:网络 作者: KLOCIC
目录Java使用Redis加锁编写LockUtil工具类使用锁redis锁用法java代码下方是java代码总结java使用redis加锁
目录
  • Java使用Redis加锁
    • 编写LockUtil工具类
    • 使用锁
  • redis锁用法java代码
    • 下方是java代码
  • 总结

    java使用redis加锁

    编写LockUtil工具类

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.connection.RedisStringCommands.SetOption;
    import org.springframework.data.redis.core.RedisCjavascriptallback;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.data.redis.core.types.Expiration;
    import org.springframework.stereotype.Sandroidervice;
    
    /**
    * LockUtil <br>
    *
    */
    @Service
    public class LockUtil {
    
      @Autowired
      private RedisTemplate redisTemplate;
    
      @Autowirhttp://www.devze.comed
      private StringRedisTemplate stringRedisTemplate;
    
      /**
      * @param lockKey 上锁的key
      * @param lockSeconds 上锁的秒数
      * @return
      */
      public boolean lock(String lockKey, int lockSeconds) {
        return (Boolean) redisTemplate.execute((RedisCallback) connection -> {
          byte[] key = lockKey.getBytes();
          Boolean set = connection.set(key, key, Expiration.seconds(lockSeconds), SetOption.SET_IF_ABSENT);
          if (set == null) {
            return false;
          }
          return set;
        });
      }
    
      public boolean isLock(String lockKey) {
        return stringRedisTemplate.opsForValue().get(lockKey)!=null;
      }
    
    
      public boolean clearLock(String lockKey){
       return redisTemplate.delete(lockKey);
      }
    }

    使用锁

    public abstract class AbstractTask {
    
      @Autowired
      private LockUtil lockUtil;
    
      /**
      * 获取redis锁的key
      *
      * @return
      */
      protected abstract String getLockKey();
    
      protected boolean lock() {
        return lockUtil.lock(getLockKey(), 120);
      }
    
      protected boolean lockManual() {
        return lockUtil.lock(getLockKey(), 299);
      }
    
      protected boolean clearLock() {
        return lockUtil.clearLock(getLockKey());
      }
    }
    @Component
    @Slf4j
    @RefreshScope
    public class FileCapaciwww.devze.comtyCountTask extends AbstractTask{
      @Autowired
      private Fil开发者_Js入门eCapacityCountService fileCapacityCountService;
     
    
      @Scheduled(cron = "${BATch.verification.schedule.capacity}")
      public void task(){
        if (!lock()) {
          log.info("本实例无需执行定时任务");
          return;
        }
        fileCapacityCountService.fileCapacityCountTask();
      }
    
      @Override
      protected String getLockKey() {
        String today = DateUtil.formatDate(new Date());
        return FileCapacityCountTask.class.getSimpleName() + CommonConstant.APPLICATION_NAME + today;
      }
    }

    redis锁用法java代码

    由于redis是串行的,所以可以用redis实现锁机制。

    下方是java代码

    @Component
    @Slf4j
    public class RedisSingleLock {
        private final StringRedisTemplate redis;
    
        public SimpleDistributedLock(StringRedisTemplate redis) {
            this.redis = redis;
        }
    
        //这个方法,可以传入key加锁;多线程调用时,只有1个能获取锁成功,其它线程则会进入循环,不停尝试获取锁
        public void lock(String key) {
            do {
                Boolean lockSuccess = redis.opsForValue().setIfAbsent(key, "1", 1, TimeUnit.DAYS);
                if (lockSuccess == null) {
                    throw new IllegalStateException();
                }
                if (!lockSuccess) {
                    try {
                        TimeUnit.MILLISECONDS.sleep(100);
                    } catch (InterruptedException e) {
                        log.error(e.getMessage(), e);
                    }
                } else {
                    break;
                }
            } while (true);
        }
    
        //这个方法,传入key释放锁,当持有锁的线程执行业务代码完毕后调用,释放这个锁;上方某一个在lock方法中循环尝试获得锁的线程可以获得锁,另外的线程则继续循环等待
        public void releaseLock(String key) {
            redis.delete(key);
        }
    	
    	//这个方法只尝试获取一次锁,返回获取结果
        public boolean tryLock(String key) {
            Boolean lockSuccess = redis.opsForValue().setIfAbsent(kpythoney, "1", 1, TimeUnit.DAYS);
            if (lockSuccess == null) {
                throw new IllegalStateException();
            }
    
            return lockSuccess;
        }
    }
    
        
    
    

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消