java实现分布式锁
package com.yiran.redis;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import java.net.PortUnreachableException;
/**
* @program: BigdataSrc
* @description:
* @author: Mr.Yang
* @create: 2021-05-15 14:41
**/
public class RdisTest1 {
public static Jedis conn = new Jedis("hadoop102", 6379);
/**
* 分布式锁的设计:
* 全局进程可访问
* 具有唯一性,拿到所的进程or线程执行任务,其他阻塞
* 集群异常处理
* 防止死锁):
* 集群在释放锁之前挂了
* 数据丢失):
* 客户端在数据拿到锁后,redis服务挂掉
* 解决方案:
* 使用setnx争抢锁
* 使用expire设置过期时间
* 问题:
* setnx 之后 expire之前服务挂了
* 使用set nx ex实现一致性操作
*/
@Test
public void dbs_lock1(){
Long count=100L;
conn.set("java_count","100");
while(true) {
// 实现分布式锁 set k v nx ex time
String lock = conn.set("java_lock", String.valueOf(1), "nx", "ex", 1000);
System.out.println(lock + "hello");
if ("OK".equals(lock) && count>=1) {
count = conn.decr("java_count");
System.out.println(count);
conn.del("java_lock");
}else {
break;
}
}
}
/**
* 实现互斥锁
*/
@Test
public void dbs_lock2(){
Long count=100L;
conn.set("java_count","100");
String threadName = Thread.currentThread().getName();
while(true) {
// 实现分布式锁 set k v nx ex time
// 实现唯一id
String lock = conn.set("java_lock", threadName, "nx", "ex", 1000);
System.out.println(lock + "hello");
if ("OK".equals(lock) && count>=1) {
count = conn.decr("java_count");
System.out.println(count);
// 实现唯一id判断
if (threadName.equals(conn.get("java_lock"))) {
conn.del("java_lock");
}
}else {
break;
}
}
}
/**
* 实现可重入锁
* 保证当前线程可重复提交
* synchornized就是可重入锁:底层做了判断,放行连续拿到锁的情况
*/
@Test
public void dbs_lock3(){
Long count=100L;
conn.set("java_count","100");
String threadName = Thread.currentThread().getName();
while(true) {
// 实现分布式锁 set k v nx ex time
// 实现唯一id
String lock = conn.set("java_lock", threadName, "nx", "ex", 1000);
System.out.println(lock + "hello");
// 此处逻辑修改 实现可重入锁
if (("OK".equals(lock) || threadName.equals(conn.get("java_lock"))) && count>=1) {
count = conn.decr("java_count");
System.out.println(count);
// 实现唯一id判断
if (threadName.equals(conn.get("java_lock"))) {
conn.del("java_lock");
}
}else {
break;
}
}
}
}