【1】-3 Reentrance Lockout (重入锁死)

来源:互联网 发布:c语言中char是几位 编辑:程序博客网 时间:2024/06/16 09:03

Reentrance lockout 【重入锁死】 is a situation similar to deadlock and nested monitor lockout. Reentrance lockout is also covered in part in the texts on Locks and Read / Write Locks.

Reentrance lockout may occur if a thread reenters a Lock, ReadWriteLock or some other synchronizer that is not reentrant. Reentrant means that a thread that already holds a lock can retake it. Java's synchronized blocks are reentrant. Therefore the following code will work without problems:

译文:

重入锁死类似于死锁嵌套管程锁死
重入锁死已经在  Locks and Read / Write Locks 讲到了.

当一个线程重新获得锁,读写锁(这里提到的锁都是指的不可重入的锁实现,并不是java类库中的 LockReadWriteLock)或者其他不可重入的同步器时,就可能发生重入锁死。

可重入意味着一个线程获得锁之后还能重新获得锁。

Java的synchronized  块是可重入的。

下面的代码没有任何问题:


public class Reentrant{  public synchronized outer(){    inner();  }  public synchronized inner(){    //do something  }}

Notice how both outer() and inner() are declared synchronized, which in Java is equivalent to asynchronized(this) block. If a thread calls outer() there is no problem calling inner() from inside outer(), since both methods (or blocks) are synchronized on the same monitor object ("this").

 If a thread already holds the lock on a monitor object, it has access to all blocks synchronized on the same monitor object. This is called reentrance. The thread can reenter any block of code for which it already holds the lock.

The following Lock implementation is not reentrant:


译文:
注意到 outer()和 inner() 都定义了synchronized ,在java中 这等价于 synchronized(this) 。

如果一个线程调用了outer()然后在outer()内部调用inner() 时没问题的,尽管两个方法(或块)在同一个监控对象object ("this") 上加了synchronized 。

如果一个线程在一个monitor 对象上已经持有了锁,它就可以访问所有在这个monitor对象有synchronized 块的入口(或方法)。

这就是“重入”。这个线程可以重新访问任何持有monitor 对象的锁的代码。


下面的Lock的实现是不可重入的:


public class Lock{  private boolean isLocked = false;  public synchronized void lock()  throws InterruptedException{    while(isLocked){      wait();    }    isLocked = true;  }  public synchronized void unlock(){    isLocked = false;    notify();  }}

If a thread calls lock() twice without calling unlock() in between, the second call to lock() will block. A reentrance lockout has occurred.

To avoid reentrance lockouts you have two options:

  1. Avoid writing code that reenters locks
  2. Use reentrant locks

Which of these options suit your project best depends on your concrete situation. Reentrant locks often don't perform as well as non-reentrant locks, and they are harder to implement, but this may not necessary be a problem in your case. Whether or not your code is easier to implement with or without lock reentrance must be determined case by case.


译文:
如果一个线程调用了lock() 两次而没有调用  unlock()两次,第二次调用  lock()时将会阻塞。
一个重入锁死 问题就出现了:

为了解决这个问题你有2中方案:
  1、编写代码时避免再次获取已经持有的锁。
  2、使用可重入锁。

至于选择哪个最适合你的项目,的视情况具体而定。

可重入锁通常没有不可重入锁那么好的表现,而且实现起来复杂,但是这些情况在你的项目中也许算不上什么问题。
无论你的项目用锁来实现方便还是不用锁方便,可重入特性都需要根据具体问题具体分析。


重入锁死 :  http://note.youdao.com/yws/public/redirect/share?id=10923467cb2ca01cbc30d3759eec37b3&type=false


Next: Semaphores


0 0
原创粉丝点击