以下内容转自http://ifeve.com/reentrance-lockout/

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

当一个线程重新获取锁,读写锁或其他不可重入的同步器时,就可能发生重入锁死。可重入的意思是线程可以重复获得它已经持有的锁。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()就会被阻塞,这就出现了重入锁死。

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

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

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

23、Java并发性和多线程-重入锁死的更多相关文章

  1. java 并发性和多线程 -- 读感 (一 线程的基本概念部分)

    1.目录略览      线程的基本概念:介绍线程的优点,代价,并发编程的模型.如何创建运行java 线程.      线程间通讯的机制:竞态条件与临界区,线程安全和共享资源与不可变性.java内存模型 ...

  2. Java并发性和多线程

    Java并发性和多线程介绍   java并发性和多线程介绍: 单个程序内运行多个线程,多任务并发运行 多线程优点: 高效运行,多组件并行.读->操作->写: 程序设计的简单性,遇到多问题, ...

  3. Java并发性和多线程介绍

    java并发性和多线程介绍: 单个程序内运行多个线程,多任务并发运行 多线程优点: 高效运行,多组件并行.读->操作->写: 程序设计的简单性,遇到多问题,多开线程就好: 快速响应,异步式 ...

  4. Java 并发和多线程(一) Java并发性和多线程介绍[转]

    作者:Jakob Jenkov 译者:Simon-SZ  校对:方腾飞 http://tutorials.jenkov.com/java-concurrency/index.html 在过去单CPU时 ...

  5. Java高级教程:Java并发性和多线程

    Java并发性和多线程: (中文,属于人工翻译,高质量):http://ifeve.com/java-concurrency-thread-directory/ (英文):http://tutoria ...

  6. java 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)

    参考文章:http://ifeve.com/java-concurrency-thread-directory/ 其中的竞态,线程安全,内存模型,线程间的通信,java ThreadLocal类小节部 ...

  7. 【转】JAVA 并发性和多线程 -- 读感 (二 线程间通讯,共享内存的机制)

    原文地址:https://www.cnblogs.com/edenpans/p/6020113.html 参考文章:http://ifeve.com/java-concurrency-thread-d ...

  8. 18、Java并发性和多线程-饥饿与公平

    以下内容转自http://ifeve.com/starvation-and-fairness/: 如果一个线程因为CPU时间全部被其他线程抢走而得不到CPU运行时间,这种状态被称之为“饥饿”.而该线程 ...

  9. Java 并发性和多线程

    一.介绍 在过去单 CPU 时代,单任务在一个时间点只能执行单一程序.之后发展到多任务阶段,计算机能在同一时间点并行执行多任务或多进程.虽然并不是真正意义上的“同一时间点”,而是多个任务或进程共享一个 ...

随机推荐

  1. 设置VMWare虚拟机使拷贝虚拟机后固定原有的IP地址

    VMWare中已经安装并设置好的虚拟机在拷贝给别人后,再次打开该虚拟机时原有自动获取的IP地址将会变化,那么原有根据该IP地址进行的设置均将失效,还需要重新设置,比较麻烦,经过百度查询原来可以将虚拟机 ...

  2. 用SpringMVC实现的上传下载方式二(多文件上传)

    参考来源:      http://blog.csdn.net/qq_32953079/article/details/52290208 1.导入相关jar包 commons-fileupload.j ...

  3. Previous operation has not finished; run 'cleanup' if it was interrupted.SVN报错

    原因: 错误的原因是SVN管理的文件夹改名.删除文件太过频繁,导致有操作挂起了. 解决方式: 1.百度sqlite3.exe并下载. 2.将该文件解压到项目根目录下的.svn文件夹中. 3.打开cmd ...

  4. Sql2008事务日志已满处理

    处理方式: USE [master] GO ALTER DATABASE gzl SET RECOVERY SIMPLE WITH NO_WAIT GO ALTER DATABASE gzl SET ...

  5. [ CERC 2014 ] Vocabulary

    \(\\\) \(Description\) 给出三个长度分别为 \(lenA,lenB,lenC\) 的三个字符串 \(A,B,C\) ,其中字符集只包括所有小写字母以及 \(?\) 号. 现在将所 ...

  6. 一个用pyton写的监控服务端进程的软件hcm

    使用udp实现,简单,方便,不用三次握手 1. 所有部署服务器进程的机器有一个代理进程hagent,用来监听hcm console中发送过来的命令 2.hcm需要提供以下命令 start :普通方式启 ...

  7. 判断IE浏览器的类型以及提示信息(低版本浏览器不予显示)

    //浏览器IE版本判断(function(window) {    var theUA = window.navigator.userAgent.toLowerCase();    if ((theU ...

  8. angular6 NG-ZORRO 的使用

    1:关于 NG-ZORRO中使用它自己组件改变样式时得使用样式穿透 “class” :: ng-deep "class"

  9. Jmeter接口测试---get和post及解决乱码问题

    Jmeter接口测试---get请求 1.创建一个线程组 测试计划---添加---Threads ---线程组 2.添加http请求,步骤如下图所示: 3.添加带有参数的get请求,如下图展示内容: ...

  10. 关于vue构建项目的一些指令

    第一步: brew install nodejs(MAC机子下)  Windows直接官网下载对应版本node.js 第二步: 获取nodejs模块安装目录访问权限(Windows系统忽略)sudo ...