文章目录
前言
对于java中死锁的学习,予以记录!
一、什么是死锁?
1、概念
死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象
若无外力干涉那它们都将无法推进下去,如果系统资源充足,进程的资源请求都能得到满足,死锁出现的可能性就很低。否则就会因争夺有限的资源而陷入死锁。
2、产生死锁的主要原因
- 系统资源不足
- 进程运行推进的顺序不合适
- 资源分配不当
3、死锁产生的必要条件:互斥、请求保持、不可抢占与循环等待
-
互斥条件:进程对所分配到的资源进行排它性使用,即在一段时间内,某资源只能被一个进程占用。如果此时还有其它进程请求该资源,则请求进程只能等待,直至占有该资源的进程用毕释放。
-
请求保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程被阻塞,但又对自己以获得的资源保持不变。
-
不可抢占条件:进程已获得的资源在未使用完之前不能被抢占,只能在进程使用完时由自己释放。
-
循环等待条件:在发生死锁时,必定存在一个由进程构成的资源循环链(进程集合{P0,P1,P2,…,Pn}中的P0正在等待一个P1占用的资源,P1正在等待P2占用的资源,…,Pn正在等待P0占用的资源)。
二、写一个死锁Demo
class ShareDeadLock implements Runnable{
private String lockA;
private String lockB;
public ShareDeadLock(String lockA, String lockB) {
this.lockA = lockA;
this.lockB = lockB;
}
@Override
public void run() {
synchronized (lockA){
System.out.println(Thread.currentThread().getName()+"\t持有锁:"+lockA+"尝试获得锁:"+lockB);
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lockB){
System.out.println(Thread.currentThread().getName()+"\t持有锁:"+lockB+"尝试获得锁:"+lockA);
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class DeadLock {
public static void main(String[] args) {
String lockA="lockA";
String lockB="lockB";
new Thread(new ShareDeadLock(lockA,lockB),"ThreadAAA").start();
new Thread(new ShareDeadLock(lockB,lockA),"ThreadBBB").start();
}
}
三、如何定位死锁?
1、jps -l:确定进程号
2、jstack 进程号:定位死锁
3、jconsole图形化界面监视管理控制台