重入锁死
来源:互联网 发布:keil c语言 编辑:程序博客网 时间:2024/06/06 03:35
重入锁死与死锁和嵌套管程锁死非常相似。锁和读写锁两篇文章中都有涉及到重入锁死的问题。
当一个线程重新获取锁,读写锁或其他不可重入的同步器时,就可能发生重入锁死。可重入的意思是线程可以重复获得它已经持有的锁。Java的synchronized块是可重入的。因此下面的代码是没问题的:
(译者注:这里提到的锁都是指的不可重入的锁实现,并不是Java类库中的Lock与ReadWriteLock类)
public class Reentrant{public synchronized outer(){inner();}public synchronized inner(){//do something}}
注意outer()和inner()都声明为synchronized,这在Java中这相当于synchronized(this)块(译者注:这里两个方法是实例方法,synchronized的实例方法相当于在this上加锁,如果是static方法,则不然,更多阅读:哪个对象才是锁?)。如果某个线程调用了outer(),outer()中的inner()调用是没问题的,因为两个方法都是在同一个管程对象(即this)上同步的。如果一个线程持有某个管程对象上的锁,那么它就有权访问所有在该管程对象上同步的块。这就叫可重入。若线程已经持有锁,那么它就可以重复访问所有使用该锁的代码块。
下面这个锁的实现是不可重入的:
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();}}
如果一个线程在两次调用lock()间没有调用unlock()方法,那么第二次调用lock()就会被阻塞,这就出现了重入锁死。
避免重入锁死有两个选择:
- 编写代码时避免再次获取已经持有的锁
- 使用可重入锁
至于哪个选择最适合你的项目,得视具体情况而定。可重入锁通常没有不可重入锁那么好的表现,而且实现起来复杂,但这些情况在你的项目中也许算不上什么问题。无论你的项目用锁来实现方便还是不用锁方便,可重入特性都需要根据具体问题具体分析。
原创文章,转载请注明: 转载自并发编程网 – ifeve.com本文链接地址: 重入锁死
- 重入锁死
- 重入锁死
- java 重入锁死
- 【1】-3 Reentrance Lockout (重入锁死)
- Java并发系列-21、重入锁死
- 死锁的三种形式:一般死锁,嵌套管程锁死,重入锁死
- 死锁的三种形式:一般死锁,嵌套管程锁死,重入锁死
- Windows下Myeclipse不能卸载的解决方案Failed to load Library jvm
- 线程
- ERROR: JAVA_HOME is set to an invalid directory: C:\Program Files\Java\jdk1.8.0_ 73\bin
- BZOJ 1040 骑士 (并查集 树形dp)
- 读书笔记---Head First 设计模式--- 观察者模式
- 重入锁死
- 线性代数中的余子式、代数余子式、行列式、伴随矩阵、逆矩阵
- 形象化解析TCP/IP、Http的区别
- 文章标题
- 我为什么鼓励工程师写blog
- 信号量
- OpenTSDB数据写入HTTP API接口,统计总记录数
- 正确编译 DuiLib 静态库的方法
- 程序员装X指南:能说专业术语尽量别说人话