• java 基于redis分布式锁


    1、基于redis分布式锁

    package com.example.demo;
    
    
    
    import org.apache.commons.lang3.StringUtils;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.stereotype.Component;
    
    import java.util.concurrent.TimeUnit;
    
    @Component
    public class DistributedLockComponent {
    
        @Autowired
        StringRedisTemplate stringRedisTemplate;
    
        private org.slf4j.Logger logger = LoggerFactory.getLogger(this.getClass());
    
        /**
         *
         * @desc 加锁
         * @param key
         * @param value
         * @param timeout 超时时间
         * @param autoReleaseTime 自动释放锁时间
         */
        public boolean lock(String key, String value, long timeout, long autoReleaseTime) {
            boolean flag = true;
    
            long time = System.currentTimeMillis();
            long maxTime = time + timeout;
    
            // 自旋等待-如果在指定时间内还没获取到锁就退出自旋,并且设置过期时间避免死锁。
            while (!stringRedisTemplate.opsForValue().setIfAbsent(key, value) && time <= maxTime) {
                try {
                    TimeUnit.MICROSECONDS.sleep(10);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    flag = false;
                    break;
                }
    
                time = System.currentTimeMillis();
            }
    
            // 设置过期时间
            if (flag) {
                stringRedisTemplate.expire(key, autoReleaseTime, TimeUnit.MILLISECONDS);
            }
    
            return flag;
        }
    
        /**
         *
         * @desc 解锁
         * @param key
         * @param value
         */
        public void unLock(String key, String value) {
            try {
                if(StringUtils.isNotBlank(stringRedisTemplate.opsForValue().get(key))
                        && stringRedisTemplate.opsForValue().get(key).equals(value)) {
                    stringRedisTemplate.delete(key);
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        }
    
    
        /**
         * 扣减库存
         */
        public String decreaseStock(String key, String value){
            try{
                lock(key,value,6000,6000 * 2);
            }catch (Exception e){
                logger.error(e.getMessage(),e);
            }finally {
                unLock(key,value);
            }
            return "";
        }
    
    
        /**
         *  测试可模拟多个线程扣减库存
         * @param skuId 商品ID
         */
        public String test(String skuId) {
    
            decreaseStock("KEY_SKU_"+skuId, skuId);
    
            //线程1
            new Thread(()->{
                decreaseStock("KEY_SKU_"+skuId, skuId);
            });
    
            //线程2
            new Thread(()->{
                decreaseStock("KEY_SKU_"+skuId, skuId);
            });
    
            return "";
        }
    
    
    }
  • 相关阅读:
    什么是原型(prototype)
    angularjs input指令
    angularjs 弹出框 $modal (转)
    windows下安装wabt
    windows下安装emscripten
    windows下安装mingw
    windows下安装git
    windows下安装cmake
    windows下安装python
    trunc与round
  • 原文地址:https://www.cnblogs.com/chenweichu/p/13450013.html
Copyright © 2020-2023  润新知