阅读 76

单机redisson使用redis锁,遇到的问题记录

1.引入jar包

<dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency>      <groupId>org.redisson</groupId>      <artifactId>redisson</artifactId>      <version>3.11.1</version>      </dependency> <dependency> 复制代码

2.application.properties添加配置文件

server.port=8998 spring.redis.host=127.0.0.1 #Redis服务器连接端口 spring.redis.port=6379 #Redis服务器连接密码(默认为空) spring.redis.password= #连接池最大连接数(使用负值表示没有限制) spring.redis.jedis.pool.max-active=500 spring.redis.jedis.pool.max-idle=1000 spring.redis.jedis.pool.max-wait=6000ms spring.redis.jedis.pool.min-idle=4 #连接超时时间(毫秒) spring.redis.timeout=30000 # redisson lock redisson.address=redis://127.0.0.1:6379 redisson.password= 复制代码

3.新建redisson 配置类

import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /**  * redisson 配置类  * Created on 2018/6/19  */ @Configuration public class RedissonConfig {     @Value("${spring.redis.host}")     private String host;     @Value("${spring.redis.port}")     private String port;     @Value("${spring.redis.password}")     private String password;     @Bean     public RedissonClient getRedisson(){         Config config = new Config();         config.useSingleServer().setAddress("redis://" + host + ":" + port)        //心跳检测,定时与redis连接,可以防止一段时间过后,与redis的连接断开         .setPingConnectionInterval(1000)         ;         //添加主从配置 //        config.useMasterSlaveServers().setMasterAddress("").setPassword("").addSlaveAddress(new String[]{"",""});         return Redisson.create(config);     } } 复制代码

4.测试类

import com.zhipeng.testspringboot.redission.RedissonService; import org.redisson.api.RLock; import java.util.concurrent.TimeUnit; public class TestIt {    static int number =0 ;     public static int testredis(RedissonService redissonService){         RLock lock =null;         try {             lock = redissonService.getRLock("record2Ids");             if (!lock.isLocked()){                 lock.lock(30, TimeUnit.MINUTES);                 number++;                 System.out.println(Thread.currentThread().getName()+"->:"+number);                 return 1;             }else{                 System.err.println(Thread.currentThread().getName() +"->:"+"被锁住了");                 return 0;             }         }finally {             if (null != lock && lock.isLocked() && lock.isHeldByCurrentThread()){                 lock.unlock();             }         }     } } 复制代码

多线程调用此方法时,出现一个异常
问题描述

当我们使用Ression中Lock.lock()方法之后,如果存在线程并发常见情况下,会出现如下异常: java.lang.IllegalMonitorStateException: attempt to unlock lock, not locked by current thread by node id: 9f178836-f7e1-44fe-a89d-2db52f399c0d thread-id: 22

问题分析 在thread-1还没有结束的时候,也就是在thread-1在获得锁但是还没有释放锁的时候, `thread-2进入了try代码块内,获取不到锁后退出,进入了finally代码块,并且将thread-1的锁尝试解锁。所以thread-2并没有获得锁,还尝试去释放锁导致的。

问题解决

在finally里面添加判断 lock.isHeldByCurrentThread()

// 是当前执行线程的锁 if (lock.isHeldByCurrentThread()){ } 复制代码

同样的解决方法,可以解决当前方法执行超时后,锁自动释放,又在finally自动释放导致的问题。


作者:普金在中东散步
链接:https://juejin.cn/post/6992514166376382471


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐