小黑有点困,他想休息,又怕耽误时间,于是准备小眯一会。
网站建设哪家好,找创新互联!专注于网页设计、网站建设、微信开发、小程序设计、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了宁蒗免费建站欢迎大家使用!
为了能按时起来,他设了闹钟,作为程序员,必须得整两个,防止单点故障。
当任意一个闹钟响起,小黑就起来把两个闹钟都关掉,继续干活,就像这样:
public class Clock {
private BlackBro blackBro;
public void setBlackBro(BlackBro blackBro) {
this.blackBro = blackBro;
}
public synchronized void ring() {
System.out.println(Thread.currentThread() + " Clock.ring...");
blackBro.wake();
}
public synchronized void close() {
System.out.println(Thread.currentThread() + " Clock.close...");
}
}
public class BlackBro {
private Clock[] clocks;
public void setClocks(Clock[] clocks) {
this.clocks = clocks;
}
public synchronized void wake() {
System.out.println(Thread.currentThread() + "BlackBro.wake...");
for (Clock clock : clocks) {
clock.close();
}
}
}
为了防止闹钟和小黑在执行操作期间被人打扰,我贴心地给他们都加上了锁 —— synchronized。
模拟这个场景将是这样:
public static void main(String[] args) {
Clock clock1 = new Clock();
Clock clock2 = new Clock();
BlackBro blackBro = new BlackBro();
clock1.setBlackBro(blackBro);
clock2.setBlackBro(blackBro);
blackBro.setClocks(new Clock[]{clock1, clock2});
// sleep...
Thread t1 = new Thread(clock1::ring);
Thread t2 = new Thread(clock2::ring);
t1.start();
t2.start();
}
启动程序发现,陷入了无尽地等待:
Thread[Thread-0,5,main] Clock.ring...
Thread[Thread-1,5,main] Clock.ring...
Thread[Thread-1,5,main]BlackBro.wake...
这是怎么回事?眼尖的同学肯定发现问题了。我们看一下 jstack:
Found one Java-level deadlock:
=============================
"Thread-0":
waiting to lock monitor 0x0000600003ecc000 (object 0x000000070fc52398, a com.demo.BlackBro),
which is held by "Thread-1"
"Thread-1":
waiting to lock monitor 0x0000600003ec04e0 (object 0x000000070fc50f88, a com.demo.Clock),
which is held by "Thread-0"
Java stack information for the threads listed above:
===================================================
原来是死锁了:我们起了两个闹钟线程,两个线程各自拿到自己的对象锁,开始 ring,ring 又都会去唤醒小黑,但小黑对象只有一个,只有一个闹钟能顺利拿到小黑的对象锁,小黑被唤醒后又去关闹钟,但却没法关掉,因为闹钟在等小黑唤醒的期间不会被别人打断,于是闹钟在等小黑,小黑在等闹钟,形成了死锁。
我相信稍微仔细点大家都能发现这个问题,这是因为我把干扰项都排除,只留下非常简单的框架。如果在一个非常复杂的系统中,还是很难发现的。这也是我今天遇到的一个线上问题,花了半天时间才排查出来。
这个 case 教育我们要谨慎使用锁,尤其是 synchronized;其次如果发现程序没有按预期地执行,尤其是该执行的没执行,可以留个心眼,看看堆栈是不是有死锁。
2024 年第一个小case送给你,你学废了吗?
当前标题:为了让小白也能看懂这个死锁Case,我请来了小黑...
标题路径:http://www.csdahua.cn/qtweb/news42/235642.html
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网