redis 分布式锁demo
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<relativePath/>
</parent>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.3.0</version>
</dependency>
public class ThreadDemoMain {
public static void main(String[] args) {
RedisPool redisPool = new RedisPool();
ProductService productService = new ProductService();
ProducerService p1 = new ProducerService("生产者p1", productService);
ProducerService p2 = new ProducerService("生产者p2", productService);
CustomerService c1 = new CustomerService("消费者c1", productService);
CustomerService c2 = new CustomerService("消费者c2", productService);
CustomerService c3 = new CustomerService("消费者c3", productService);
p1.start();
p2.start();
c1.start();
c2.start();
c3.start();
}
}
public class ProductService {
public final static int MAX_NUM = 20;
public final static int MIN_NUM = 5;
public volatile Integer productNum = 10;
public final String lock = "111";
public final static ReentrantLock LOCK = new ReentrantLock();
public final static Condition CONDITION = LOCK.newCondition();
public void add() throws InterruptedException {
//synchronized (lock) {
//LOCK.lock();
if (!RedisTool.tryGetDistributedLock(RedisPool.getJedis(),lock,Thread.currentThread().getName(),20)) {
return;
}
if (RedisTool.tryGetDistributedLock(RedisPool.getJedis(),lock,Thread.currentThread().getName(),20)) {
System.out.println(Thread.currentThread().getName()+"第二次获取锁成功!");
}
System.out.println(Thread.currentThread().getName()+"获取锁成功!");
productNum++;
System.out.println(Thread.currentThread().getName() + "生产1,当前总数量:" + productNum);
TimeUnit.SECONDS.sleep(10);
// if (productNum >= MAX_NUM) {
// System.out.println("仓库满了!不生产了!");
// //CONDITION.await(100);
// lock.wait();
// }
//LOCK.unlock();
//}
if (RedisTool.releaseDistributedLock(RedisPool.getJedis(),lock,Thread.currentThread().getName())) {
System.out.println(Thread.currentThread().getName()+"释放锁成功!");
}else {
System.out.println(Thread.currentThread().getName()+"释放锁失败!");
}
System.out.println("---------------------------------");
}
public void sub() {
//synchronized (lock) {
//LOCK.lock();
if (!RedisTool.tryGetDistributedLock(RedisPool.getJedis(),lock,Thread.currentThread().getName(),1000)) {
return;
}
System.out.println(Thread.currentThread().getName()+"获取锁成功!");
if (productNum > 0) {
productNum--;
System.out.println(Thread.currentThread().getName() + "消费1,剩余总数量:" + productNum);
// if (productNum <= MIN_NUM) {
// System.out.println("快没货了,赶紧生产!!!");
// //CONDITION.signalAll();
// lock.notify();
// }
}
//LOCK.unlock();
//}
if (RedisTool.releaseDistributedLock(RedisPool.getJedis(),lock,Thread.currentThread().getName())) {
System.out.println(Thread.currentThread().getName()+"释放锁成功!");
}else {
System.out.println(Thread.currentThread().getName()+"释放锁失败!");
}
System.out.println("---------------------------------");
}
}
public class CustomerService extends Thread {
private ProductService productService;
public CustomerService(String name, ProductService productService) {
super(name);
this.productService = productService;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
buy();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
break;
}
}
System.out.println(Thread.currentThread().getName() + "停止消费");
}
public void buy() throws InterruptedException {
productService.sub();
//TimeUnit.MILLISECONDS.sleep(1000);
}
}
public class ProducerService extends Thread {
private ProductService productService;
public ProducerService(String name, ProductService productService) {
super(name);
this.productService = productService;
}
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
make();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
e.printStackTrace();
break;
}
}
System.out.println(Thread.currentThread().getName() + "停止生产");
}
public void make() throws InterruptedException {
productService.add();
//TimeUnit.MILLISECONDS.sleep(500);
}
}
public class RedisTool {
private static final String LOCK_SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "NX";
private static final String SET_WITH_EXPIRE_TIME = "PX";
private static final Long RELEASE_SUCCESS = 1L;
/**
* 尝试获取分布式锁
*
* @param jedis Redis客户端
* @param lockKey 锁
* @param requestId 请求标识
* @param expireTime 超期时间
* @return 是否获取成功
*/
public static boolean tryGetDistributedLock(Jedis jedis, String lockKey, String requestId, int expireTime) {
SetParams setParams = new SetParams();
//nx() 相当于setnx()方法
setParams.nx();
//设置过期时间 ex 单位秒 px 单位毫秒
setParams.ex(expireTime);
String result = jedis.set(lockKey, requestId, setParams);
jedis.close();
//System.out.println(Thread.currentThread().getName()+"---redis分布式锁加锁结果:" + result);
if (LOCK_SUCCESS.equals(result)) {
return true;
}
return false;
}
/**
* 释放分布式锁
*
* @param jedis Redis客户端
* @param lockKey 锁
* @param requestId 请求标识
* @return 是否释放成功
*/
public static boolean releaseDistributedLock(Jedis jedis, String lockKey, String requestId) {
System.out.println(Thread.currentThread().getName()+"---redis分布式锁释放锁");
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
jedis.close();
System.out.println(Thread.currentThread().getName()+"---redis分布式锁释放锁结果:" + result);
if (RELEASE_SUCCESS.equals(result)) {
return true;
}
return false;
}
}
public class RedisPool {
private static JedisPool pool;//jedis连接池
private static int maxTotal = 20;//最大连接数
private static int maxIdle = 10;//最大空闲连接数
private static int minIdle = 5;//最小空闲连接数
private static boolean testOnBorrow = true;//在取连接时测试连接的可用性
private static boolean testOnReturn = false;//再还连接时不测试连接的可用性
static {
initPool();//初始化连接池
System.out.println("RedisPool初始化完成");
}
public static Jedis getJedis(){
return pool.getResource();
}
public static void close(Jedis jedis){
jedis.close();
}
private static void initPool(){
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(maxTotal);
config.setMaxIdle(maxIdle);
config.setMinIdle(minIdle);
config.setTestOnBorrow(testOnBorrow);
config.setTestOnReturn(testOnReturn);
config.setBlockWhenExhausted(true);
pool = new JedisPool(config, "127.0.0.1", 6379, 5000, "redis");
}
}
redission 分布式锁demo
Config config1 = new Config();
config1.useSingleServer().setAddress("redis://127.0.0.1:16379")
.setPassword("a123456").setDatabase(0);
RedissonClient redissonClient1 = Redisson.create(config1);
Config config2 = new Config();
config2.useSingleServer().setAddress("redis://127.0.0.1:26379")
.setPassword("a123456").setDatabase(0);
RedissonClient redissonClient2 = Redisson.create(config2);
Config config3 = new Config();
config3.useSingleServer().setAddress("redis://127.0.0.1:36379")
.setPassword("a123456").setDatabase(0);
RedissonClient redissonClient3 = Redisson.create(config3);
String resourceName = "REDLOCK";
RLock lock1 = redissonClient1.getLock(resourceName);
RLock lock2 = redissonClient2.getLock(resourceName);
RLock lock3 = redissonClient3.getLock(resourceName);
RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);
boolean isLock;
try {
isLock = redLock.tryLock(500, 30000, TimeUnit.MILLISECONDS);
System.out.println("isLock = "+isLock);
if (isLock) {
//TODO if get lock success, do something;
Thread.sleep(30000);
}
} catch (Exception e) {
} finally {
// 无论如何, 最后都要解锁
System.out.println("");
redLock.unlock();
}