死锁
两个或两个以上的进程在执行过程中,相互争抢资源造成相互等待的现象,若无外力干涉他们这种状态将一直持续下去.死锁可能会出现程序假死.当资源充足的情况下,进程的资源请求都能得到满足,出现死锁几率较低,但在争抢有限资源的情况下可能会陷入死锁
产生死锁的原因
- 系统资源不足
- 进程运行顺序不当
- 资源分配不当
死锁产生的四个必要条件
- 互斥
- 解决方法: 把互斥的共享资源封装成可同时访问
- 占有且等待
- 解决方法: 进程请求资源时,要求不占用任何其他资源,也就是他必须一次性申请到所有资源,这种方式会导致资源效率低
- 非抢占式
- 解决方法: 如果进程不能立即分配资源,要求它不占用任何其他资源,也就是只能同时获得所有资源时,才会执行分配操作
- 循环等待
- 解决方法: 堆资源进行排序,要求进程按顺序请求资源
死锁问题代码
package com.corn.juc.lock;
import java.util.concurrent.TimeUnit;
/** 控制输出 程序卡死
* Thread1 enter get LCOK1
* Thread2 enter get LOCK2
*/
class TestThread implements Runnable {
private final String lock1;
private final String lock2;
public TestThread(String lock1, String lock2) {
this.lock1 = lock1;
this.lock2 = lock2;
}
@Override
public void run() {
synchronized (lock1) {
System.out.println(Thread.currentThread().getName() + "\t enter get " + lock1);
try {
// 模拟耗时操作
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock2) {
System.out.println(Thread.currentThread().getName() + "\t enter get lock2" + lock2);
}
}
}
}
public class DeadLockDemo {
private static final String LOCK1 = "LCOK1";
private static final String LOCK2 = "LOCK2";
public static void main(String[] args) {
new Thread(new TestThread(LOCK1, LOCK2), "Thread1").start();
new Thread(new TestThread(LOCK2, LOCK1), "Thread2").start();
}
}
查看死锁命令
- jsp -l 查看出所有java进程获取JID
jps -l
14432 com.corn.juc.lock.DeadLockDemo
15248 org.jetbrains.jps.cmdline.Launcher
3984 org.jetbrains.kotlin.daemon.KotlinCompileDaemon
9520
1188 sun.tools.jps.Jps
14152 org.jetbrains.jps.cmdline.Launcher
2456 org.jetbrains.jps.cmdline.Launcher
- jstack JID 查看java进程栈信息
Java stack information for the threads listed above:
===================================================
"Thread2":
at com.corn.juc.lock.TestThread.run(DeadLockDemo.java:37)
- waiting to lock <0x00000000d5aac710> (a java.lang.String) // 等待lock
- locked <0x00000000d5aac748> (a java.lang.String) // 被某一个lock锁住
at java.lang.Thread.run(Thread.java:745)
"Thread1":
at com.corn.juc.lock.TestThread.run(DeadLockDemo.java:37)
- waiting to lock <0x00000000d5aac748> (a java.lang.String) //同上
- locked <0x00000000d5aac710> (a java.lang.String) //同上
at java.lang.Thread.run(Thread.java:745)
Found 1 deadlock. // 找到一个死锁 Thread2 和 Thread1 相互等待