1. 什么是死锁?什么情况会发生死锁?
-
线程死锁是指由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行,就会产生死锁。
-
饥饿是指线程因为种种原因无法获取所需要的资源,导致线程一直无法执行。
2. 死锁产生原因
系统资源的竞争导致系统资源不足,以及资源分配不当,导致死锁。
进程在运行过程中,请求和释放资源的顺序不当,会导致死锁。
3. 死锁的前提(4个必要条件)
- 互斥条件:一个资源每次只能被一个进程使用,即在一段时间内某 资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。
- 请求与保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源 已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。
- 不可剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
- 循环等待条件: 若干进程间形成首尾相接循环等待资源的关系
4. 怎么去观察死锁的,比如用java命令
- Jconsole查看死锁:进入java安装的位置,输入Jconsole,然后弹出界面(或者进入安装目录/java/jdk1.70_80/bin/,点击Jconsole.exe),可以检测死锁。
- Jstack查看死锁:进入jdk安装目录的bin下面,输入jps,先查看我们要检测死锁的进程;然后可以看到进程Test的进程号:****,然后执行:Jstack -l **** 来看死锁信息
5. 遇到了死循环该怎么办。该怎么查询?JAVA自带的命令知道吗?
- top:找到占用CPU最大的进程号
- top -Hp 进程号:查看指定进程下的线程,选出占用比较高的线程号,将线程号转化为16进制,拿到转换后的十六进制,在线程dump中进行查找
6. 如何避免(预防)死锁?
- 避免一个线程同时获取多个锁
- 避免一个线程在锁内同时占用多个资源
- 尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制
- 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况
7. 如何预防死锁
通过破坏死锁产生的4个必要条件来 预防死锁
8. 发生死锁怎么办?
- 最简单、最常用的方法就是进行系统的重新启动
- 撤消进程,剥夺资源。
- 进程回退策略,即让参与死锁的进程回退到没有发生死锁前某一点处,并由此点处继续执行,以求再次执行时不再发生死锁。