
本文主要介绍Java线程死锁示例和解决方案. 本文介绍的示例代码非常详细. 它对每个人的学习或工作都有一定的参考价值. 需要它的朋友可以参考它.
1. 死锁的定义
所谓的死锁是由多个线程争用资源引起的(彼此等待)死锁. 没有外力,这些进程将无法前进.

2. 僵局的必要条件
互斥条件: 线程需要对分配的资源(例如打印机)进行独占控制,也就是说,某个资源在一段时间内仅被一个线程占用. 如果线程此时请求资源,则请求线程只能等待.
非剥夺条件: 在不使用线程获取的资源之前,它不能被其他线程夺走,也就是说,只能由获取资源本身的线程释放它(只能处于活动状态已发布).

请求和保留条件: 该线程保留了至少一个资源,但是发出了新的资源请求,并且该线程已经被另一个线程占用. 这时,请求过程被阻止,但是它不维护已获取的资源. 放.
循环等待条件: 有一个循环等待的线程资源链,并且链中的下一个线程同时请求链中的每个线程. 也就是说,在等待状态下有一组线程{P1,P2,...,Pn},其中Pi等待P(i +1)占用的资源(i = 0,1,..,n -1),Pn等待资源被P0占用java多线程死锁java多线程死锁,如下所示.


3. 死锁的例子
/**
* 一个简单的死锁类
* 当DeadLock类的对象flag==1时(td1),先锁定o1,睡眠500ms
* 而td1在睡眠的时候另一个flag==0的对象(td2)线程启动,先锁定o2,睡眠500ms
* td1 睡眠结束后需要锁定 o2 才能继续执行,而此时 o2 已被 td2 锁定;
* td2 睡眠结束后需要锁定 o1 才能继续执行,而此时 o1 已被 td1 锁定;
* td1、td2 相互等待,都需要得到对方锁定的资源才能继续执行,从而死锁。
*/
public class DeadLock implements Runnable {
public int flag = 1;
//静态对象是类的所有对象共享的
private static Object o1 = new Object(), o2 = new Object();
@Override
public void run() {
System.out.println("flag="+flag);
if(flag==1){
synchronized (o1){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o2){
System.out.println("1");
}
}
}
if(flag==0){
synchronized (o2){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (o1){
System.out.println("0");
}
}
}
}
public static void main(String[] args) {
DeadLock td1 = new DeadLock();
DeadLock td2 = new DeadLock();
td1.flag=1;
td2.flag=0;
//td1,td2都处于可执行状态,但JVM线程调度先执行哪个线程是不确定的。
//td2的run()可能在td1的run()之前运行
new Thread(td1).start();
new Thread(td2).start();
}
}


4. 如何避免死锁
在某些情况下可以避免死锁. 避免死锁的两种技术
1)锁定顺序(线程以一定顺序锁定

2)锁定时间限制(程获取锁定时添加一定的时间限制,超过该时间限制后放弃对锁定的请求,并释放其持有的锁定)

以上是本文的全部内容. 希望对大家的学习有所帮助. 我也希望每个人都支持该脚本主页.
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-159181-1.html
事后毙我也行