13 死锁
Posted cathy_mu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了13 死锁相关的知识,希望对你有一定的参考价值。
线程 A 持有资源 2,线程 B 持有资源 1,他们同时都想申请对方的资源。
public class Demo{
private static Object resource1 = new Object();
private static Object resource2 = new Object();
public static void main(String[] args){
new Tread(
()->{
synchronized (resource1){
//do something
try{
Thread.sleep(1000);//为了让线程2得到执行
}catch(Exception e){
//do something
}
synchronized(resource2){
//do something
}
}
},"线程1"
).start();
new Tread(
()->{
synchronized (resource2){
//do something
try{
Thread.sleep(1000);//为了让线程1得到执行
}catch(Exception e){
//do something
}
synchronized(resource2){
//do something
}
}
},"线程2"
).start();
}
}
死锁四个条件
1.互斥:资源只能由一个线程持有
2.保持:阻塞时,保持持有已有资源
3.不剥夺:没有权利剥夺其他线程持有的资源,只能资源释放
4.循环:若干线程之间形成头尾相接的循环等待
如何预防死锁
1.破坏保持:一次性申请所有资源
2.破坏不剥夺:
3.破坏循环:按序申请资源
//将线程2的代码改成这样,按资源1 资源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();
sleep和wait的区别
sleep 不释放锁,自动苏醒
wait 释放锁,需要等别的线程调用notify 或notifyall,或者用wait(时间)
调start时会自动调run,为什么不能直接调run
new一个新线程,线程进入新建状态,调用start方法,会启动一个线程并使线程进入就绪状态,分配到时间片就可以运行了,start会执行线程的准备工作,然后自动执行run方法的内容。
直接调run方法,只是执行了呀一个普通方法,没有在某个线程中执行他,不是多线程工作。
以上是关于13 死锁的主要内容,如果未能解决你的问题,请参考以下文章