java的死锁与解决方法
一、什么是死锁?
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无限等待。
二、产生死锁的原因与四个条件
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的死锁与解决方法的更多相关文章
- Tomcat 优化 java.lang.OutOfMemoryError: Java heap space 的解决方法
Tomcat 优化 java.lang.OutOfMemoryError: Java heap space 的解决方法 java.lang.OutOfMemoryError: Java heap sp ...
- java.lang.ClassNotFoundException的解决方法
java.lang.ClassNotFoundException的解决方法 出现这个问题的原因可能很多,但是最终原因都是部署的项目文件中没有这个类包. 那么出错的点在哪呢?逐一排除! 1.首先在项 ...
- SqlServer表死锁的解决方法
SqlServer表死锁的解决方法 前些天写一个存储过程,存储过程中使用了事务,后来我把一些代码注释掉来进行调试找错,突然发现一张表被锁住了,原来是创建事务的代码忘记注释掉.本文表锁住了的解决方法 ...
- Tomcat部署java项目java.lang.OutOfMemoryError异常解决方法
java.lang.OutOfMemoryError异常解决方法 Window系统环境下,在catalina.bat文件第一行添加以下内容 set JAVA_OPTS=-Xms512m -Xmx512 ...
- 对于jfinal中java.lang.Long cannot be cast to java.lang.Integer的解决方法
@Jfinal 老大提供的解决方法 当数据库字段为 int 型(有符号int型),但是如果在 sql 中使用了某些函数,jdbc 会自动转型为 long,例如:select sum(money) fr ...
- android 工程里缺少 R.java 文件原因和解决方法
作为新手,学习android 的时候难免要导入一些示例,目的为了更加了解android各种API用法,顺便也可以学习下别人代码的写法. 可是导入android源码后,基本都有错误,R.java也不会自 ...
- Java中线程出现Exception in thread "Thread-0" java.lang.IllegalMonitorStateException异常 解决方法
代码 package thread; public class TestChongNeng { public static void main(String[] args) { Thread t1 = ...
- Java线程死锁查看分析方法
如何查看是否有Java线程死锁?下面介绍两种方法. 一.Jconsole Jconsole是JDK自带的图形化界面工具,使用JDK给我们的的工具JConsole,可以通过打开cmd然后输 ...
- (转)Android工程出现 java.lang.NoClassDefFoundError错误解决方法
在Eclipse中,导入Android工程,工程没有报错,运行时,出现 java.lang.NoClassDefFoundError类没有找到的错误.从问题上可以看出是导入包出错的原因.遂百度加谷歌. ...
- Java小问题的解决方法系列
1)IDEA中文乱码,解决方法:http://blog.csdn.net/zht666/article/details/8953516 2)卸载OpenJdk,http://my.oschina.ne ...
随机推荐
- CF319D 题解
题意 传送门 给你一个字符串 \(S\),要求你每次找到一个最短的并且最左边的形如 \(XX\)(即由两个相同的字符串拼接而成)的子串,然后把这个字符串从 \(XX\) 变成 \(X\).问无法操作后 ...
- YYYY-MM-dd
Calendar calendar = Calendar.getInstance(); calendar.set(2019, Calendar.DECEMBER, 31); Date strDate ...
- ASP.NET Core中使用日志组件NLog
上一篇文章描述了如何在ASP.NET Core中使用Log4Net记录日志.本篇将使用另外一个组件NLog在ASP.NET Core中记录日志. 1.引入程序集 NLog.Web.AspNetCore ...
- node_exporter安装
1.node_exporter下载 node_exporter-1.3.1.linux-amd64.tar.gz tar -xzvf node_exporter-1.3.1.linux-amd64.t ...
- 几款Android 应用自动化测试工具
本文转自:https://blog.csdn.net/hebbely/article/details/78901466 简述: 本文介绍几款流行的 Android应用自动化测试工具. Monkey测试 ...
- swoole的使用场景
一.TCP服务器 二.UDP服务器 三.HTTP服务器 四.WebSocket服务器 五.物联网服务器 六.执行异步任务 七.协程
- OpenEuler 中C与汇编的混合编程
2.5.1用汇编代码编程 将C代码编译成汇编代码 C代码: /**********a.c file********/ #include <stdio.h> extern int B(); ...
- python中的字典数据读取
①字典中嵌套字典 res1={'content': {'age': '47岁', 'ageOne': 47, 'ageOneUnit': '1', 'ageTwo': '8', 'ageTwoUnit ...
- react+antd pro实现【列表可实时行内编辑】的弹窗表单组件
纯列表版效果展示: ① 初始无值,展示为唤醒按钮+文案外链 ②点击按钮唤醒弹窗(简易版示意图) ③配置后 可编辑表格组件文档: https://procomponents.ant.design/com ...
- Arthas 查询服务器内存数据
1.打开Arthas所在位置 eg:/home 2.java -jar arthas-boot.jar 运行jar包 3.选择要执行的java jar包 eg : 1 4.执行查看命令vmtool - ...