# redis-utils **Repository Path**: wuxi_zero/redis-utils ## Basic Information - **Project Name**: redis-utils - **Description**: redis公共类的使用 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2019-11-15 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # redis-utils #### 介绍 自定义redis公共类的使用 #### 使用的技术 这里使用的是springboot为基础的项目 #### 安装教程 ``` org.springframework.boot spring-boot-starter-data-redis ``` #### 开始了 **自定义redis分布式锁** ``` 类的接口名为 redisService @Override public boolean lock(String key, String value) { value = getLockValue(value); if (stringRedisTemplate.opsForValue().setIfAbsent(key, value)) { //setNX 返回boolean return true; } return false; } private static final String PRE = "_"; /** * 始终保证当前线程持有 * * @param value 标识当前线程持有 * @return String */ private String getLockValue(String value) { return value + PRE + Thread.currentThread().getId(); } @Override public void unlock(String key, String value) { //保证当前线程是锁的持有者 value = getLockValue(value); String currentValue = stringRedisTemplate.opsForValue().get(key); if (!StringUtils.isEmpty(currentValue) && currentValue.equals(value)) { stringRedisTemplate.opsForValue().getOperations().delete(key); } } ``` _说明一下:_ 1.getLockValue : 这个方法它的作用很简单保证了这个锁只能被持有它的现成所释放。这点很重要,特别在高并发的情况下,极端情况下,同一个毫秒内可能会发生多个请求达到相同的服务中,如果不能保证持有锁的线程是释放锁的线程,可能会发生,非锁持有者线程去释放锁,导致脏数据。 2.setIfAbsent 这个方法保证了在redis中这个key不会被多次赋值,底层是用了setNX的方式。我这里使用的方式是没有超时间的那种,所以需要手动释放。 3.如果使用的一下方式去处理是不会出现死锁的。 **使用方式** ``` @GetMapping("/lock") public Result lock(){ String keyLock = "wx.test.key.5"; String key = "wx-testKey5"; //这个无法测试一些极端情况,基本上使用jmeter测试不出来,比如同一个毫秒内发生的并发。 Long valueLock = System.currentTimeMillis(); try { if(redisService.lock(keyLock,valueLock.toString())){ if(StringUtils.isBlank(redisService.get(key))){ redisService.set(key,"0"); } else{ redisService.set(key,redisService.get(key)+"1"); } //表示业务处理的时间 Thread.sleep(10000L); }else{ System.out.println("-----------已经有锁了啊啊啊-------->"); } }catch (Exception e){ e.printStackTrace(); }finally { redisService.unlock(keyLock,expireTime.toString()); } System.out.println("-------keylock---------->"+redisService.get(keyLock)+"---------------------->"+redisService.get(key)); return Result.successBase(); } ```