博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于redis实现的分布式锁
阅读量:6327 次
发布时间:2019-06-22

本文共 2064 字,大约阅读时间需要 6 分钟。

 

基于redis实现的分布式锁

我们知道,在多线程环境中,锁是实现共享资源互斥访问的重要机制,以保证任何时刻只有一个线程在访问共享资源。锁的基本原理是:用一个状态值表示锁,对锁的占用和释放通过状态值来标识,因此基于redis实现的分布式锁主要依赖redis的SETNX命令和DEL命令,SETNX相当于上锁,DEL相当于释放锁,当然,在下面的具体实现中会更复杂些。之所以称为分布式锁,是因为客户端可以在redis集群环境中向集群中任一个可用Master节点请求上锁(即SETNX命令存储key到redis缓存中是随机的)。

 

现在相信你已经对在基于redis实现的分布式锁的基本概念有了解,需要注意的是,这个和前面文章提到的使用WATCH 命令对key值进行锁操作没有直接的关系。java中synchronized和Lock对象都能对共享资源进行加锁,下面我们将学习用java实现的redis分布式锁。

java中的锁技术

在分析java实现的redis分布式锁之前,我们先来回顾下java中的锁技术,为了直观的展示,我们采用“多个线程共享输出设备”来举例。

不加锁共享输出设备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public 
class 
LockTest {
    
//不加锁
    
static 
class 
Outputer {
        
public 
void 
output(String name) {
            
for
(
int 
i=
0
; i<name.length(); i++) {
                
System.out.print(name.charAt(i));
            
}
            
System.out.println();
        
}
    
}
    
public 
static 
void 
main(String[] args) {
        
final 
Outputer output = 
new 
Outputer();
        
//线程1打印zhangsan
        
new 
Thread(
new 
Runnable(){
            
@Override
            
public 
void 
run() {
                
while
(
true
) {
                     
try
{
                         
Thread.sleep(
1000
);
                     
}
catch
(InterruptedException e) {
                         
e.printStackTrace();
                     
}
                     
output.output(
"zhangsan"
);
                
}  
            
}
        
}).start();
         
        
//线程2打印lingsi
        
new 
Thread(
new 
Runnable(){
            
@Override
            
public 
void 
run() {
                
while
(
true
) {
                     
try
{
                         
Thread.sleep(
1000
);
                     
}
catch
(InterruptedException e) {
                         
e.printStackTrace();
                     
}
                     
output.output(
"lingsi"
);
                
}
            
}
        
}).start();
         
        
//线程3打印wangwu
        
new 
Thread(
new 
Runnable(){
            
@Override
            
public 
void 
run() {
                
while
(
true
) {
                     
try
{
                         
Thread.sleep(
1000
);
                     
}
catch
(InterruptedException e) {
                         
e.printStackTrace();
                     
}
                     
output.output(
"huangwu"
);
                
}
            
}
        
}).start();
    
}
}

 

上面例子中,三个线程同时共享输出设备output,线程1需要打印zhangsan,线程2需要打印lingsi,线程3需要打印wangwu。在不加锁的情况,这三个线程会不会因为得不到输出设备output打架呢,我们来看看运行结果:

 

1
2
3
4
5
6
7
8
9
10
11
huangwu
zhangslingsi
an
huangwu
zlingsi
hangsan
huangwu
lzhangsan
ingsi
huangwu
lingsi

  

从运行结果可以看出,三个线程打架了,线程1没打印完zhangsan,线程2就来抢输出设备......可见,这不是我们想要的,我们想要的是线程之间能有序的工作,各个线程之间互斥的使用输出设备output。

 

http://www.cnblogs.com/hjwublog/p/5749929.html

 https://my.oschina.net/91jason/blog/517996?p=1

转载于:https://www.cnblogs.com/softidea/p/5981337.html

你可能感兴趣的文章
剑指offer 数组中只出现一次的数字
查看>>
打造个人的vimIDE
查看>>
2019中山大学程序设计竞赛 Enlarge it(水题)
查看>>
BZOJ 4259 FFT
查看>>
POJ 2455 二分+网络流
查看>>
POJ 3280 DP
查看>>
装箱和拆箱
查看>>
golang 文件导入数据追加sheet
查看>>
switch 和 if...else if 的区别
查看>>
CSS3响应式布局之弹性盒子
查看>>
遇到问题集锦
查看>>
lnmp环境下piwiki网站流量分析工具的安装及配置
查看>>
saltstack自动化运维系列③之saltstack的常用模块使用
查看>>
shell编程系列18--文本处理三剑客之awk动作中的条件及if/while/do while/for循环语句...
查看>>
工控安全资料
查看>>
单元测试基础知识(转)
查看>>
ArrayList和LinkedList区别
查看>>
使用原理视角看 Git
查看>>
消息队列的面试题6
查看>>
最小割dp Intel Code Challenge Final Round (Div. 1 + Div. 2, Combined) E
查看>>