我们已经知道可以通过Redis自带的函数setNX来实现分布式锁,具体实现步骤如下。
我在一台CentOS7的linux虚拟机中安装了Redis服务,ip地址为:192.168.246.130,服务端口为:6379。
下面是java通过redis实现分布式锁的例子:
import redis.clients.jedis.Jedis;
public class RedisLock {
//锁的key
private static final String key = "DistributedRedisLock";
private static Integer count = 0;
public static void main(String[] args) {
for(int i=0;i<1000;i++){
new Thread(new Runnable() {
@Override
public void run() {
//获取Redis连接
Jedis jedis = new Jedis("192.168.246.130", 6379);
try{
while(true){
//获取锁
if(jedis.setnx(key, Thread.currentThread().getName()) == 1){
try{
System.out.println("线程("+Thread.currentThread().getName()+")获取到锁,开始执行操作");
count++;
System.out.println(count);
break;
}finally{
System.out.println("操作执行完成,释放锁");
//操作执行完一定要释放锁,所以在finally块中执行
jedis.del(key);
}
}else{
//返回的不是1,说明已经有某个线程获取到了锁
try {
//等待100毫秒之后重试
Thread.sleep(100l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
//释放Redis连接
jedis.disconnect();
}
}
}).start();
}
}
}
上述代码的输出结果为:
线程(Thread-320)获取到锁,开始执行操作
1
操作执行完成,释放锁
线程(Thread-463)获取到锁,开始执行操作
2
操作执行完成,释放锁
线程(Thread-997)获取到锁,开始执行操作
3
操作执行完成,释放锁
...
线程(Thread-409)获取到锁,开始执行操作
998
操作执行完成,释放锁
线程(Thread-742)获取到锁,开始执行操作
999
操作执行完成,释放锁
线程(Thread-286)获取到锁,开始执行操作
1000
操作执行完成,释放锁
上述代码虽然是在单应用多线程情况下测试的,但即便是在分布式环境下多应用多线程去获取锁,结果依然是正确的。
---------------------