java 锁的重入_Java 的可重入锁和不可重入锁

可重入锁又名递归锁,是指在同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提锁对象得是同一个对象或者class),不会因为之前已经获取过还没释放而阻塞。Java中ReentrantLock和synchronized都是可重入锁,可重入锁的一个优点是可一定程度避免死锁。

13578.html

定义

可重入锁:当线程获取某个锁后,还可以继续获取它,可以递归调用,而不会发生死锁;

不可重入锁:与可重入相反,获取锁后不能重复获取,否则会产生死锁。

不可重入锁

所谓不可重入锁,即若当前线程执行某个方法已经获取了该锁,那么在方法中尝试再次获取锁时,就会获取不到被阻塞。我们尝试设计一个不可重入锁:

1

2

3

4

5

6

7

8

9

10

11

12

13publicclassLock{

privatebooleanisLocked=false;

publicsynchronizedvoidlock()throwsInterruptedException{

while(isLocked){

wait();

}

isLocked=true;

}

publicsynchronizedvoidunlock(){

isLocked=false;

notify();

}

}

使用该锁:

1

2

3

4

5

6

7

8

9

10

11

12

13publicclassCount{

Locklock=newLock();

publicvoidprint(){

lock.lock();

doAdd();

lock.unlock();

}

publicvoiddoAdd(){

lock.lock();

//do something

lock.unlock();

}

}

当前线程执行print()方法首先获取lock,接下来执行doAdd()方法就无法执行doAdd()中的逻辑,必须先释放锁。这个例子很好的说明了不可重入锁。

可重入锁

可重入锁的实现:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24publicclassLock{

booleanisLocked=false;

ThreadlockedBy=null;

intlockedCount=0;

publicsynchronizedvoidlock()

throwsInterruptedException{

Threadthread=Thread.currentThread();

while(isLocked&& lockedBy != thread){

wait();

}

isLocked=true;

lockedCount++;

lockedBy=thread;

}

publicsynchronizedvoidunlock(){

if(Thread.currentThread()==this.lockedBy){

lockedCount--;

if(lockedCount==0){

isLocked=false;

notify();

}

}

}

}

所谓可重入,意味着线程可以进入它已经拥有的锁的同步代码块儿。

我们设计两个线程调用print()方法,第一个线程调用print()方法获取锁,进入lock()方法,由于初始lockedBy是null,所以不会进入while而挂起当前线程,而是是增量lockedCount并记录lockBy为第一个线程。接着第一个线程进入doAdd()方法,由于同一进程,所以不会进入while而挂起,接着增量lockedCount,当第二个线程尝试lock,由于isLocked=true,所以他不会获取该锁,直到第一个线程调用两次unlock()将lockCount递减为0,才将标记为isLocked设置为false。

可重入锁的概念和设计思想大体如此,Java中的可重入锁ReentrantLock设计思路也是这样。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值