一、什么是死锁?

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无限等待。

二、产生死锁的原因与四个条件

2.1 死锁原因

竞争资源

  多个线程竞争同一个不可剥夺的系统资源,或者多个线程竞争同一个临时资源(包括缓存、信号、消息、对象数据等)

  补充:系统资源分为两类:可剥夺资源(CPU、主存等),不可剥夺资源(打印机、声卡等等输出设备)

推进顺序不合理(获取锁的顺序不合理)

  程序运行的顺序不合理,进程一获取资源A后,此时进程二获取资源B,然后进程一想获取资源B,进程二想获取资源A;这两个进程互相不释放资源,就会死锁

2.2 四个条件

  • 互斥:同一资源在同一时间只能被同一进程使用
  • 请求与保持:进程在拥有一个资源时,坚决保持此资源,并且一直去请求另外的新资源
  • 不可剥夺:进程已经拥有的资源在未使用完之前,不可以被剥夺,只能在使用完被释放,也可说唯一占有
  • 环路等待:进程一直等待新资源,产生了环形链

三、死锁案例

public class DeadLock {
public static void main(String[] args) {
ArrayList<String> listA = new ArrayList<>();
ArrayList<String> listB = new ArrayList<>();
final Object A = new Object();
final Object B = new Object();

new Thread(() -> {
synchronized (listA) {
System.out.println("线程一获取到对象A的锁");
listA.add("A");
try {
Thread.sleep(500);
synchronized (listB) {
System.out.println("线程一获取到对象B的锁");
}
} catch (InternalError | InterruptedException e) {
e.printStackTrace();
}
}
}).start();

new Thread(() -> {
synchronized (listB) {
System.out.println("线程二获取到对象B的锁");
listB.add("B");
try {
Thread.sleep(500);
synchronized (listA) {
System.out.println("线程二获取到对象A的锁");
}
} catch (InternalError | InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}

运行后就可以发现,线程一、二会一直等待对方锁持有的锁

四、防止死锁的方法

破坏死锁四个条件中的一个就可以防止死锁

  • 资源一次性分配:一次性分配所有资源,这样就不会再有请求了:(破坏请求条件)
  • 只要有一个资源得不到分配,也不给这个进程分配其他的资源:(破坏请保持条件)
  • 可剥夺资源:即当某进程获得了部分资源,但得不到其它资源,则释放已占有的资源(破坏不可剥夺条件)
  • 资源有序分配法:系统给每类资源赋予一个编号,每一个进程按编号递增的顺序请求资源,释放则相反(破坏环路等待条件)

具体应用方法(说人话)

(1) 确定锁的顺序,并且整个应用中都按照这个顺序来获取锁。

例如:我们上面的 Demo 中,两个线程获取锁的顺序都为 先获取对象 a 的锁,在获取对象 b 的锁,就不会出现死锁的问题。

(2) 超时放弃

  当使用synchronized关键词提供的内置锁时,只要线程没有获得锁,那么就会永远等待下去。此时我们一般需要避免嵌套锁

  然而我们可以用其它的锁:

  • Lock接口提供了boolean tryLock(long time, TimeUnit unit) throws InterruptedException方法,该方法可以按照固定时长等待锁,因此线程可以在获取锁超时以后,主动释放之前已经获得的所有的锁。通过这种方式,也可以很有效地避免死锁。
  • 采用分布式锁,加上锁的时限,那么锁就不会无限等待了

java的死锁与解决方法的更多相关文章

  1. Tomcat 优化 java.lang.OutOfMemoryError: Java heap space 的解决方法

    Tomcat 优化 java.lang.OutOfMemoryError: Java heap space 的解决方法 java.lang.OutOfMemoryError: Java heap sp ...

  2. java.lang.ClassNotFoundException的解决方法

    java.lang.ClassNotFoundException的解决方法   出现这个问题的原因可能很多,但是最终原因都是部署的项目文件中没有这个类包. 那么出错的点在哪呢?逐一排除! 1.首先在项 ...

  3. SqlServer表死锁的解决方法

    SqlServer表死锁的解决方法   前些天写一个存储过程,存储过程中使用了事务,后来我把一些代码注释掉来进行调试找错,突然发现一张表被锁住了,原来是创建事务的代码忘记注释掉.本文表锁住了的解决方法 ...

  4. Tomcat部署java项目java.lang.OutOfMemoryError异常解决方法

    java.lang.OutOfMemoryError异常解决方法 Window系统环境下,在catalina.bat文件第一行添加以下内容 set JAVA_OPTS=-Xms512m -Xmx512 ...

  5. 对于jfinal中java.lang.Long cannot be cast to java.lang.Integer的解决方法

    @Jfinal 老大提供的解决方法 当数据库字段为 int 型(有符号int型),但是如果在 sql 中使用了某些函数,jdbc 会自动转型为 long,例如:select sum(money) fr ...

  6. android 工程里缺少 R.java 文件原因和解决方法

    作为新手,学习android 的时候难免要导入一些示例,目的为了更加了解android各种API用法,顺便也可以学习下别人代码的写法. 可是导入android源码后,基本都有错误,R.java也不会自 ...

  7. Java中线程出现Exception in thread "Thread-0" java.lang.IllegalMonitorStateException异常 解决方法

    代码 package thread; public class TestChongNeng { public static void main(String[] args) { Thread t1 = ...

  8. Java线程死锁查看分析方法

    如何查看是否有Java线程死锁?下面介绍两种方法. 一.Jconsole        Jconsole是JDK自带的图形化界面工具,使用JDK给我们的的工具JConsole,可以通过打开cmd然后输 ...

  9. (转)Android工程出现 java.lang.NoClassDefFoundError错误解决方法

    在Eclipse中,导入Android工程,工程没有报错,运行时,出现 java.lang.NoClassDefFoundError类没有找到的错误.从问题上可以看出是导入包出错的原因.遂百度加谷歌. ...

  10. Java小问题的解决方法系列

    1)IDEA中文乱码,解决方法:http://blog.csdn.net/zht666/article/details/8953516 2)卸载OpenJdk,http://my.oschina.ne ...

随机推荐

  1. c语言学习---void 数据类型

    这样的语法是错误的: void a = 10;  void表示无类型, 这样定义一个变量a, 编译器是无法知道给a分配多大的内存空间的 #include<stdio.h> #include ...

  2. PO 锁

    SAP NetWeaver Administrator->可用性和监控->资源监控->锁

  3. 简单的python线程池实现线程安全demo

    from concurrent.futures import ThreadPoolExecutor import threading import time import sys sys.path.a ...

  4. Python中用eval将字符串转换为字典时候出错:NameError: name ‘null’ is not defined的解决方法

    这两天在用python调用接口时,因为接口返回的是str类型的数据,形如: 因为这样的str类似字典,所以我想把它转为字典以便处理,使用的是eval来进行转换,如下:   <pre name=& ...

  5. Web Dynpro for ABAP(16):WDA Analysis Tools

    3.21 Quality Assurance and Supportability WDA程序效能验证工具. Tests工具: eCATT and Web Dynpro ABAP Debugging工 ...

  6. Mysql语句练习

    某宾馆其关系模式如下:Room(房间编号,房间类型,价格)Customer(顾客编号,顾客姓名,年龄,电话)RC(房间号,顾客编号,入住日期,入住天数) 1 create database Hotel ...

  7. kafka例子

    <dependencies> <dependency> <groupId>org.apache.kafka</groupId> <artifact ...

  8. Unity中实现在规定时间内从一个值递增到另一个值

    1.进度条(在规定时间内完成进度条) private Image progressBar; private float currentProgress = 0; /// <summary> ...

  9. PostgreSQL 存储过程 通过设定条件,返回指定的数据表记录

    PL/pgSQL是 PostgreSQL 数据库系统的一个可装载的过程语言. PL/pgSQL的设计目标是创建一种可装载的过程语言,可以可用于创建函数和触发器过程, 在SQL语言中添加控制结构功能, ...

  10. MLR算法双面网络时钟

    MLR算法双面网络时钟------专业LED时钟厂家![点击进入] MLR算法双面网络时钟 NTP电子时钟功能说明: 双面NTP电子时钟采用独特结构设计,可根据客户要求订制显示布局:年.月.日.时.分 ...