死锁的产生原因是两个线程在互相等待对方,上代码:
package thread;
/**
* @ClassName Test8
* @Author 瞿肖
* @Date 2022/7/11 16:23
*/
public class Test8 implements Runnable {
static A a = new A();
static B b = new B();
/**
* @flg false:A说,true:B说
*/
boolean flg = false;
@Override
public void run() {
if (flg) {
synchronized (a) {
a.suo();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (b) {
b.get();
}
}
} else {
synchronized (b) {
b.suo();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (a) {
a.get();
}
}
}
}
public static void main(String[] args) {
Test8 te1 = new Test8();
Test8 te2 = new Test8();
te1.flg = false;
te2.flg = true;
Thread t1 = new Thread(te1);
Thread t2 = new Thread(te2);
t1.start();
t2.start();
}
}
查找的方法是:
在编译器的中断输入:jps
终端会输出线程数据:
10160 Launcher
11860
9128 Test8
5964 Jps
找到和文件名相同的例如:9128 Test8
然后在输入:jstack 9128
就能看见一堆数据;
找到:"Thread-1":
at thread.Test8.run(Test8.java:28)
- waiting to lock <0x00000000d660a648> (a thread.B)
- locked <0x00000000d66081e8> (a thread.A)
at java.lang.Thread.run(Thread.java:748)
at thread.Test8.run这个就是产生死锁的地方
waiting to lock 等待某一个id解锁,而B线程也在等A线程解锁,就导致了互相等待。
产生的地方是:
synchronized (b) {
b.suo();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (a) {
a.get();
}
}
将b线程锁住的同时,在里面又给了一个锁住a的锁,然而a在它自己的线程里面也被锁住了
就造成了两个线程都被锁住了,解决方法就是将其中一个锁拿出锁外,变成这样:
synchronized (b) {
b.suo();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
synchronized (a) {
a.get();
}
这样这样b就能释放锁,然后a线程又能进行获得b的锁,继续释放锁。
解决方案:
破解一下因素其中一个即可!
产生死锁的四大因素!!!
一、互斥:
共享资源只能被一个线程占用————————————————互斥锁
二、占有等待:
本线程的执行条件是另外一个线程执行完毕————————等待对方释放资源
三、不可抢占:
资源只能由持有它的线程自愿释放、其他线程不可强行占有该资源。——无法释放对方资源
四、循环等待:
线程a等待线程b释放资源,线程b等待线程a释放资源。———两个线程互相等待对方