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 ...
随机推荐
- el-input 限制输入框只能输入数字和小数
方法一: oninput ="value=value.replace(/[^\d]/g,'')" //只能输入数字 oninput ="value=value.repla ...
- SQL SERVER 多表联合修改
sql server中有时候会用到多表联合修改,下面是简单的多表修改的例子 UPDATE a SET a.a1 = b.b1 , a.a2 = b.b2 FROM A a, B b WHERE a.a ...
- Safari浏览器如何收藏网页?
Safari浏览器是MacOS所自带的一款功能强劲的浏览器,许多MacOS的用户在使用过Safari浏览器后就不会去下载其他浏览器了.对于很多Mac新手用户来说,如何使用Safari浏览器来收藏喜欢的 ...
- freertos 启动任务调度器后卡在svc 0,汇编停在了0x0800014A E7FE B 0x0800014A
分别引导加载程序和应用程序(带有或不带有FreeRTOS)都可以正常工作. 引导加载程序和应用程序(无需FreeRTOS)可以完美运行. 但是,如果我在应用程序中使用freeRTOS并完成两项任务(显 ...
- python3+selenium+BeautifulReport生成自动化测试报告
https://www.jianshu.com/p/3d2c0e092ffb 自动化测试,最重要的还是测试报告,下面就教大家使用BeautifulReport生成自动化测试报告GitHub:https ...
- 在windows下使用dbus
介绍 DBUS是一种很方便的IPC远程调用的通信机制.可以很方便地调用其他进程提供的函数,甚至是不同计算机上提供的函数,内部通过TCP套接字进行相互通信. 不过甚至你可以修改成其他通信方式,比如USB ...
- Opengl数学markdown
# opengl数学 $$\begin{Bmatrix} {A_{x}}\\ {A_{y}}\\ {A_{z}}\\ \end{Bmatrix} * \begin{Bmatrix} {B_{x}}\\ ...
- MATLAB 多行注释
自用的两种方法 1: %{ 若干语句 } % 2.快捷键CTRL+R,取消注释CTRL+T
- Linux挂载tf卡空间
https://blog.csdn.net/cao849861802/article/details/126039190
- AI基本知识
一.什么是flops 对flops有疑惑,首先得先捋清这个概念: FLOPS:注意全大写,是floating point operations per second的缩写,意指每秒浮点运算次数,理解为 ...