在分布式的情况下,我们没法使用本地的锁进行加锁从而实现并发同步,这个使用我们就需要使用到redis实现的分布式锁了 这里的话介绍的是redisson,也是官方推荐使用的
步骤
1、导入依赖
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.15.5</version>
</dependency>
2、编写application.yml
spring:
redis:
host: 127.0.0.1
port: 6379
password:
redisson:
file: classpath:redisson.yml
3、在resource下面创建redisson.yml
singleServerConfig:
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
password:
subscriptionsPerConnection: 5
clientName: myredis
address: redis://127.0.0.1:6379
subscriptionConnectionMinimumIdleSize: 1
subscriptionConnectionPoolSize: 50
connectionMinimumIdleSize: 32
connectionPoolSize: 64
database: 0
dnsMonitoringInterval: 5000
codec: !<org.redisson.codec.JsonJacksonCodec> {}
transportMode : "NIO"
4、测试
方法一:test
1、编写测试类
package com.walker;
import org.apache.catalina.core.ApplicationContext;
import org.junit.jupiter.api.Test;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class RedissonTest {
@Autowired
private RedissonClient redissonClient;
private final static String LOCK="I_AM_LOCK";
@Test
public void test1() throws InterruptedException {
RLock lock = redissonClient.getLock(LOCK);
for (int i = 0; i < 5; i++) {
new Thread(()->{
lock.lock();
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+":\t 获得锁");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
System.out.println(Thread.currentThread().getName()+":\t 释放锁锁");
lock.unlock();
}
}).start();
}
Thread.sleep(100000);
}
}
2、测试
执行测试方法,之后发现每次只有一个线程可以获取锁和释放锁
方法二:controller
1、编写controller
编写两个方法,先执行get1方法 执行执行get2,尽量保证两个方法同时执行,会发现get1会先执行,然后由于get2获取不到锁,所以会等待一段时间之后才会执行
package com.walker.controller;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/redisson")
public class RedissonController {
@Autowired
private RedissonClient redissonClient;
private final static String LOCK="i_am_lock";
@GetMapping("/get1")
public String get1() throws InterruptedException {
RLock lock = redissonClient.getLock(LOCK);
lock.lock();
System.out.println("get1 获取数据");
Thread.sleep(4000);
lock.unlock();
return "ok";
}
@GetMapping("/get2")
public String get2(){
long start = System.currentTimeMillis();
RLock lock = redissonClient.getLock(LOCK);
lock.lock();
long time = System.currentTimeMillis()-start;
System.out.println("过了"+String.valueOf(time/1000)+"s获取锁");
System.out.println("get2 获取数据");
lock.unlock();
return "ok";
}
}
2、测试
这里get1获取锁之后输出数据,但是没有立即将锁释放 然后get2过了一段时间之后才能够拿到锁,这里的时间可能都不同,因为点击get2接口的时候有快有慢,就会导致时间不一致了, 但是都可能证明,必须要持有锁才能继续执行,否则就会进行等待
参考:https://www.cnblogs.com/h–d/p/14858848.html
|