Java中的读写锁
字面意思ReentrantReadWriteLock是在ReentrantLock的升级版
看代码示例:
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* JDK 1.8
* 保证写的时候只有一个线程在写(写线程的原子性),读的时候多个线程可以读
* @author nobt
*
* 运行结果:
1,正在写入:1
1,写入完成:1
2,正在写入:2
2,写入完成:2
4,正在写入:4
4,写入完成:4
3,正在写入:3
3,写入完成:3
5,正在写入:5
5,写入完成:5
1,正在读取:1
2,正在读取:2
3,正在读取:3
4,正在读取:4
5,正在读取:5
3,读取完成:3
1,读取完成:1
5,读取完成:5
2,读取完成:2
4,读取完成:4
* 在写入动作的时候原子性得到保证,读取的时候就不需要保证
*
*/
class Cache{
private volatile Map<String,String> map = new HashMap<>();
private ReadWriteLock rwLock = new ReentrantReadWriteLock();
/**
* 写操作
* @param key
* @param value
*/
public void put(String key,String value){
rwLock.writeLock().lock();
try{
Thread thread = Thread.currentThread();
System.out.println(thread.getName()+",正在写入:"+key);
try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
map.put(key, value);
System.out.println(thread.getName()+",写入完成:"+value);
}finally{
rwLock.writeLock().unlock();
}
}
/**
* 读操作
* @param key
*/
public void get(String key){
rwLock.readLock().lock();
try{
Thread thread = Thread.currentThread();
System.out.println(thread.getName()+",正在读取:"+key);
try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
String resultValue = map.get(key);
System.out.println(thread.getName()+",读取完成:"+resultValue);
}finally{
rwLock.readLock().unlock();
}
}
}
public class TestReadWriteLock {
public static void main(String[] args) {
Cache cache = new Cache();
for(int i = 1 ; i<=5 ; i++){
final int tempVal = i;
new Thread(() -> {
cache.put(tempVal+"", tempVal+"");
},i+"").start();
}
for(int i = 1 ; i<=5 ; i++){
final int tempVal = i;
new Thread(() -> {
cache.get(tempVal+"");
},i+"").start();
}
}
}