写点什么

Java 死锁的原因例子及解决方法,三年 Java 开发

用户头像
极客good
关注
发布于: 刚刚

System.out.println("LockB trying to lock obj1...");


synchronized(Client.obj1){


System.out.println("LockB locked obj1");


}


}


}


}catch(Exception e){


e.printStackTrace();


}


}


}


public class Client {


public static final String obj1 = "obj1";


public static final String obj2 = "obj2";


public static void main(String[] ars) {


new DeadLockA().start();


new DeadLockB().start();


}


}


运行结果:


![这里写图片描述](https://img-blo


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


g.csdn.net/20180716100407407?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2x5YWJjMTIzNDU2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)


结果显示两个线程最后都在等待对方释放锁,最终进入了死锁状态。


死锁发生的例子 2:


public class TestClass {


public synchronized void method(TestClass clazz) {


System.out.println("TestClass method in");


clazz.method2();


System.out.println("TestClass method out");


}


public synchronized void method2() {


System.out.println("TestClass method2");


}


}


public class TestLock extends Thread {


private TestClass class1;


private TestClass class2;


public TestLock(TestClass class1, TestClass class2) {


this.class1 = class1;


this.class2 = class2;


}


@Override


public void run() {


class1.method(class2);


}


}


public class Client {


public static void main(String[] ars) {


TestClass classA = new TestClass();


TestClass classB = new TestClass();


new TestLock(classA, classB).start();


new TestLock(classB, classA).start();


}


}


运行结果:



结果显示进入两次方法,但是并没有走完,发生死锁。


一旦出现死锁,整个程序既不会发生任何错误,也不会给出任何提示,只是所有线程处于阻塞状态,无法继续。java 虚拟机没有提供检测,也没有采取任何措施来处理死锁的情况,所以多线程编程中,必须手动应该采取措施避免死锁。


解决方法:


1.调整申请锁的范围


public class TestClass {


public void method(TestClass clazz) {


System.out.println("TestClass method in");


synchronized(this){


//do something


}


clazz.method2();


System.out.println("TestClass method out");


}


public synchronized void method2() {


System.out.println("TestClass method2");


}


}


上面代码原来锁是加在方法上的,现在改为在方法内的一部分,这样在使用第二个锁时本身的锁已经释放了。如果减小锁的申请范围可以避免锁的申请发生闭环的话,那么就可以避免死锁。


2.调整申请锁的顺序


在有些情况下是不允许我们调整锁的范围的,比如银行转账的场景下,我们必须同时获得两个账户上的锁,才能进行操作,两个锁的申请必须发生交叉。这时要想打破死锁闭环,必须调整锁的申请顺序,总是以相同的顺序来申请锁,比如总是先申请 id 大的账户上的锁 ,然后再申请 id 小的账户上的锁,这样就无法形成导致死锁的那个闭环。


public class Account {


private int id; // 主键


private String name;


private double balance;


public void transfer(Account from, Account to, double money){

用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
Java死锁的原因例子及解决方法,三年Java开发