0. 死锁基础知识
- 多个线程同时被阻塞,它们中的⼀个或者全部都在等待某个资源被释放。由于线程被⽆限期地阻塞,因此程序不可能正常终⽌。
- 如何避免线程死锁?

1. 产生死锁代码1
public class DeadLock {
public static void main(String[] args) {
dataSource da = new dataSource();
new Thread(() -> {
try {
da.getLockA();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "线程A").start();
new Thread(() -> {
try {
da.getLockB();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "线程B").start();
}
}
class dataSource{
private String lockA = "A锁";
private String lockB = "B锁";
public void getLockA() throws InterruptedException {
synchronized (lockA){
System.out.println(Thread.currentThread().getName() + "已经获取" +lockA);
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + "尝试获取" +lockB);
synchronized (lockB){
System.out.println(Thread.currentThread().getName() + "已经获取" +lockB);
}
}
}
public void getLockB() throws InterruptedException {
synchronized (lockB){
System.out.println(Thread.currentThread().getName() + "已经获取" +lockB);
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + "尝试获取" +lockA);
synchronized (lockA){
System.out.println(Thread.currentThread().getName() + "已经获取" +lockA);
}
}
}
}
2. 运行结果2

3.产生死锁代码2
public class DeadLockDemo {
private static Object resource1 = new Object();
private static Object resource2 = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get
resource2");
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get
resource2");
}
}
}, "线程 1").start();
new Thread(() -> {
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get
resource1");
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get
resource1");
}
}
}, "线程 2").start();
}
}
4. 运行结果2

5. 避免死锁 修改线程2(靠按序申请资源来预防)
new Thread(() -> {
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get
resource2");
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get
resource2");
}
}
}, "线程 2").start();
6. 运行结果3
