使用springboot 2.2.2 ,redis 3.0
首先这里的pom文件如下:
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.5.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
配置文件如下:application.yml
server:
port: 9030
spring:
redis:
database: 1
host: localhost
port: 6379
redisson:
address: redis://127.0.0.1:6379
配置的config类如下:
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;
@Configuration
public class RedissonConfig {
@Value("${redisson.address}")
private String addressUrl;
@Bean
public RedissonClient getRedisson() throws Exception{
RedissonClient redisson = null;
Config config = new Config();
config.useSingleServer()
.setAddress(addressUrl);
//设置看门狗的时间,不配置的话默认30000
config.setLockWatchdogTimeout(12000);
redisson = Redisson.create(config);
System.out.println(redisson.getConfig().toJSON().toString());
return redisson;
}
}
redisson的配置文件如下:
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
@Component
public class RedissonUtil {
@Autowired
private RedissonClient redissonClient; // RedissonClient已经由配置类生成,这里自动装配即可
/**
* 锁住不设置超时时间(拿不到lock就不罢休,不然线程就一直block)
* @param lockKey
* @return org.redisson.api.RLock
*/
public RLock lock(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
lock.lock();
return lock;
}
/**
* leaseTime为加锁时间,单位为秒
* @param lockKey
* @param leaseTime
* @return org.redisson.api.RLock
*/
public RLock lock(String lockKey, long leaseTime) {
RLock lock = redissonClient.getLock(lockKey);
lock.lock(leaseTime, TimeUnit.SECONDS);
return null;
}
/**
* timeout为加锁时间,时间单位由unit确定
* @param lockKey
* @param unit
* @param timeout
* @return org.redisson.api.RLock
*/
public RLock lock(String lockKey, TimeUnit unit, long timeout) {
RLock lock = redissonClient.getLock(lockKey);
lock.lock(timeout, unit);
return lock;
}
/**
* 尝试获取锁
* @param lockKey
* @param unit
* @param waitTime
* @param leaseTime
* @return boolean
*/
public boolean tryLock(String lockKey, TimeUnit unit, long waitTime, long leaseTime) {
RLock lock = redissonClient.getLock(lockKey);
try {
return lock.tryLock(waitTime, leaseTime, unit);
} catch (InterruptedException e) {
return false;
}
}
/**
* 尝试获取锁
* @param lockKey
* @param unit
* @param waitTime
* @param leaseTime
* @return boolean
*/
public boolean tryLock(String lockKey,TimeUnit unit, long waitTime) {
RLock lock = redissonClient.getLock(lockKey);
try {
return lock.tryLock(waitTime,unit);
} catch (InterruptedException e) {
return false;
}
}
/**
* 通过lockKey解锁
* @param lockKey
* @return void
*/
public void unlock(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
lock.unlock();
}
/**
* 直接通过锁解锁
* @param lock
* @return void
*/
public void unlock(RLock lock) {
lock.unlock();
}
}
controller层的代码如下
import com.exta.redission1.common.RedissonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
@RestController
@Slf4j
public class testController {
@Autowired
private RedissonUtil redissonUtil;
@RequestMapping("/get1")
public String get1(){
try{
log.info("============={} 线程访问开始============",Thread.currentThread().getName());
//TODO 尝试获取锁,等待5秒,自己获得锁后一直不解锁则7秒后自动解锁
//boolean lock = redissonUtil.tryLock("lock1", TimeUnit.SECONDS, 5L, 7L);
//进行5s的尝试时间,如果失败则返回false, 还可以设置锁过期时间,如果设置会导致看门狗无效
boolean lock = redissonUtil.tryLock("lock1", TimeUnit.SECONDS, 5L);
if (lock) {
log.info("线程:{},获取到了锁",Thread.currentThread().getName());
Thread.sleep(100);
log.info("======获得锁后进行相应的操作======" + Thread.currentThread().getName());
//redissonUtil.unlock("lock1"); //释放锁
log.info("=================" + Thread.currentThread().getName());
}
}catch (Exception e){
log.info("错误信息:{}",e.toString());
log.info("线程:{} 获取锁失败",Thread.currentThread().getName());
}
return "success";
}
}
开始的时候先把 redissonUtil.unlock("lock1"); 代码给注释掉 通过jemter测试工具可以看到 有很多线程不能执行。把 redissonUtil.unlock("lock1"); 代码打开后则大部分线程都可以得到锁了。
欢迎批评指正。