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 ""; } }
感谢您的阅读,您的支持是我写博客动力。