java中线程死锁的解决方法_Java线程死锁实例及解决方法

这篇文章主要介绍了Java线程死锁实例及解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

1、死锁的定义

所谓死锁是指多个线程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进

2、死锁产生的必要条件

互斥条件:线程要求对所分配的资源(如打印机)进行排他性控制,即在一段时间内某资源仅为一个线程所占有。此时若有线程请求该资源,则请求线程只能等待。

不剥夺条件:线程所获得的资源在未使用完毕之前,不能被其他线程倾向夺走,即只能由获得该资源的线程自己来释放(只能是主动释放)。

请求和保持条件:线程已经保持了至少一个资源,但又提出了新的资源请求,而该线程已被其他线程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。

循环等待条件:存在一种线程资源的循环等待链,链中每一个线程已获得的资源同时被链中下一个线程所请求。即存在一个处于等待状态的线程集合{P1,P2,...,Pn},其中Pi等待的资源被P(i+1)占有(i=0,1,..,n-1),Pn等待的资源被P0占有,如下图。

6b85d95c2329b732197093688c5fda23.png

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();

}

}

a956e7d6ed41245bf6ee244d88fddb28.png

4、如何避免死锁

在有些情况下死锁是可以避免的。两种用于避免死锁的技术

1)加锁顺序(线程按照一定的顺序加锁

bce96abfac8264623e86936ec2b35fcf.png

2)加锁时限(线程获取锁的时候加上一定的时限,超过时限则放弃对该锁的请求,并释放自己占有的锁)

a8c78d5438a0fc22e87f67754f5bfb63.png

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值