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()){
}
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END