可重入锁,也叫做递归锁, 指的是同一线程外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响。 在JAVA环境下 ReentrantLock 和synchronized 都是 可重入锁。 我们自己来实现一个可重入锁,可以更加透彻的理解可重入的概念
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
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.AbstractQueuedSynchronizer;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
/**
* @author xuguangwu
*/
public class MyLock implements Lock {
private Sync sync = new Sync();
public void lock() {
// sync.tryAcquire(1);
sync.acquire(1);
}
public void lockInterruptibly() throws InterruptedException {
sync.acquireInterruptibly(1);
}
public boolean tryLock() {
return sync.tryAcquire(1);
}
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(time));
}
public void unlock() {
sync.tryRelease(1);
}
public Condition newCondition() {
return sync.newConditionObj();
}
private class Sync extends AbstractQueuedSynchronizer {
@Override
protected boolean tryAcquire(int arg) {
int state = getState();
if (state == 0) {
for (; ; ) {
if (compareAndSetState(0, arg)) {
//设置当前线程占用资源
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
//这里为重入的实现
if (getExclusiveOwnerThread().equals(Thread.currentThread())) {
setState(state + arg);
return true;
}
}
}
return false;
}
@Override
protected boolean tryRelease(int arg) {
int state = getState() - arg;
boolean flag = false;
if (state == 0) {
setExclusiveOwnerThread(null);
setState(state);
return true;
}
/**
* 不存在线程安全问题,在释放前已经独占了state,重入性问题
*/
setState(state);
return false;
}
public Condition newConditionObj() {
return new ConditionObject();
}
/**
* 共享
*
* @param arg
* @return
*/
@Override
protected int tryAcquireShared(int arg) {
return super.tryAcquireShared(arg);
}
@Override
protected boolean tryReleaseShared(int arg) {
return super.tryReleaseShared(arg);
}
}
}
将核心代码圈出来
1
2
3
4
if (getExclusiveOwnerThread().equals(Thread.currentThread())) {
setState(state + arg);
return true;
}
再结合一个实际调用的案例来理解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.concurrent.locks.ReentrantLock;
public class Demo {
MyLock myLock = new MyLock();
// ReentrantLock myLock = new ReentrantLock();
public void a() {
myLock.lock();
System.out.println("a");
b();
myLock.unlock();
}
public void b() {
myLock.lock();
System.out.println("b");
myLock.unlock();
}
public static void main(String[] args) {
Demo demo = new Demo();
new Thread(() -> demo.a()).start();
}
}
新建一个线程,调用方法a(),a()中调用方法b(),两个方法都会去获取同一把锁,如果没有可重入机制, 那么就会发生死锁。ok,以上就是我对可重入锁的理解。