以下内容转自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. 构造 Codeforces Round #107 (Div. 2) B. Phone Numbers

    题目传送门 /* 构造:结构体排个序,写的有些啰嗦,主要想用用流,少些了判断条件WA好几次:( */ #include <cstdio> #include <algorithm> ...

  2. 转 PHP - AJAX 与 PHP

    1. AJAX 被用于创建交互性更强的应用程序. AJAX PHP 实例 下面的实例将演示当用户在输入框中键入字符时,网页如何与 Web 服务器进行通信: 实例 尝试在输入框中输入一个名字,如:Ann ...

  3. Kali linux 2016.2(Rolling)安装之后的常用配置

    前言 使用默认的Kali Linux设置来学习是可以的,但是我们通常要修改系统的一些基本设置,来最大化使用Kali平台的功能. 以下内容 网络的基础知识 使用图形用户界面来配置网卡 使用命令行来配置网 ...

  4. Sql2008调试问题

    t-sql调试的时候,报以下错误 处理 1.要在服务器本机,不要远程 2.服务器名称用电脑名称(cmd->hostname),不要用IP,(local)或. 调试快捷键跟VS一样 F11逐语句 ...

  5. PS如何批量整理图片大下

    https://jingyan.baidu.com/article/cdddd41cc7849853cb00e193.html

  6. Spinner实现列表下拉功能

    public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener { ...

  7. UIPageViewController 翻页、新手引导--UIScrollView:pagingEnabled

    UIPageViewController 翻页.新手引导--UIScrollView:pagingEnabled

  8. SDK_按键消息的拦截

    按键消息的拦截 拦截是为了在原有功能的基础上增加自己的操作 扩展:当按钮接收到点击消息的时候,响应的是WM_LBUTTONDOWN消息,按钮的会被这个消息打包成一个WM_COMMAND 消息发送给父窗 ...

  9. Java基本输入输出

    Java基本输入输出 基本输入 基本输出 package com.ahabest.demo; public class Test { public static void main(String[] ...

  10. react native 从头开始

    1.react-native run-android 报错SDK location not found. Define location with sdk.dir in the local.prope ...