重入锁死

简介:

原文链接 作者:Jakob Jenkov 译者:刘晓日 校对:丁一

重入锁死与死锁嵌套管程锁死非常相似。读写锁两篇文章中都有涉及到重入锁死的问题。

当一个线程重新获取读写锁或其他不可重入的同步器时,就可能发生重入锁死。可重入的意思是线程可以重复获得它已经持有的锁。Java的synchronized块是可重入的。因此下面的代码是没问题的:

(译者注:这里提到的锁都是指的不可重入的锁实现,并不是Java类库中的Lock与ReadWriteLock类)

1 public class Reentrant{
2     public synchronized outer(){
3         inner();
4     }
5  
6     public synchronized inner(){
7         //do something
8     }
9 }

注意outer()和inner()都声明为synchronized,这在Java中这相当于synchronized(this)块(译者注:这里两个方法是实例方法,synchronized的实例方法相当于在this上加锁,如果是static方法,则不然,更多阅读:哪个对象才是锁?)。如果某个线程调用了outer(),outer()中的inner()调用是没问题的,因为两个方法都是在同一个管程对象(即this)上同步的。如果一个线程持有某个管程对象上的锁,那么它就有权访问所有在该管程对象上同步的块。这就叫可重入。若线程已经持有锁,那么它就可以重复访问所有使用该锁的代码块。

下面这个锁的实现是不可重入的:

01 public class Lock{
02     private boolean isLocked = false;
03     public synchronized void lock()
04         throws InterruptedException{
05         while(isLocked){
06             wait();
07         }
08         isLocked = true;
09     }
10  
11     public synchronized void unlock(){
12         isLocked = false;
13         notify();
14     }
15 }

如果一个线程在两次调用lock()间没有调用unlock()方法,那么第二次调用lock()就会被阻塞,这就出现了重入锁死。

避免重入锁死有两个选择:

  1. 编写代码时避免再次获取已经持有的锁
  2. 使用可重入锁

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

目录
相关文章
|
14天前
|
安全 Java
大厂面试题详解:synchronized的偏向锁和自旋锁怎么实现的
字节跳动大厂面试题详解:synchronized的偏向锁和自旋锁怎么实现的
9 0
|
6月前
|
安全 算法 Java
可重入锁,不可重入锁,死锁的多种情况,以及产生的原因,如何解决,synchronized采用的锁策略(渣女圣经)自适应的底层,锁清除,锁粗化,CAS的部分应用
可重入锁,不可重入锁,死锁的多种情况,以及产生的原因,如何解决,synchronized采用的锁策略(渣女圣经)自适应的底层,锁清除,锁粗化,CAS的部分应用
|
8月前
|
存储 Java
第二季:5公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解?请手写一个自旋锁【Java面试题】
第二季:5公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解?请手写一个自旋锁【Java面试题】
32 0
|
10月前
|
安全 Java 测试技术
【JUC中的 “8锁现象” 】 —— 每天一点小知识
【JUC中的 “8锁现象” 】 —— 每天一点小知识
【JUC中的 “8锁现象” 】 —— 每天一点小知识
加了一个synchronized锁,程序就崩了
加了一个synchronized锁,程序就崩了
|
缓存 算法 Java
看完你就明白的锁系列之自旋锁
在上一篇文章 看完你就应该能明白的悲观锁和乐观锁 中我们已经学习到了什么是悲观锁和乐观锁、悲观锁和乐观锁的实现、优缺点分别是什么。其中乐观锁的实现之一 CAS 算法中提到了一个自旋锁的概念,为了全面理解 CAS 算法就首先需要了解一下自旋锁 是什么,自旋锁的适用场景和优缺点分别是什么,别着急,下面为你一一列举。
114 0
看完你就明白的锁系列之自旋锁
|
存储 安全 Java
看完你就明白的锁系列之锁的状态
前面两篇文章我介绍了一下 看完你就应该能明白的悲观锁和乐观锁 看完你就明白的锁系列之自旋锁 看完你就会知道,线程如果锁住了某个资源,致使其他线程无法访问的这种锁被称为悲观锁,相反,线程不锁住资源的锁被称为乐观锁,而自旋锁是基于 CAS 机制实现的,CAS又是乐观锁的一种实现,那么对于锁来说,多个线程同步访问某个资源的流程细节是否一样呢?换句话说,在多线程同步访问某个资源时,锁的状态会如何变化呢?本篇文章来探讨一下。
78 0
看完你就明白的锁系列之锁的状态
|
存储 安全 Java
死磕synchronized二:系统剖析延迟偏向篇一
近期准备写一个专栏:从Hotspot源码角度剖析synchronized。前前后后大概有10篇,会全网发,写完后整理成电子书放公众号供大家下载。对本专栏感兴趣的、希望彻彻底底学明白synchronized的小伙伴可以关注一波。电子书整理好了会通过公众号群发告知大家。我的公众号:**硬核子牙**。
252 0
死磕synchronized二:系统剖析延迟偏向篇一
|
监控 安全 Java
JVM Bug:多个线程持有一把锁?
JVM Bug:多个线程持有一把锁?
JVM Bug:多个线程持有一把锁?
|
Java
面试官:你给我说一下线程池里面的几个锁吧。 (下)
面试官:你给我说一下线程池里面的几个锁吧。 (下)
155 0
面试官:你给我说一下线程池里面的几个锁吧。 (下)