极客时间第二讲 什么情况下Java程序会产生 死锁?如何定位、修复?

死锁是一种特定的程序状态,在实体之间,由于循环依赖导致彼此一处于等待之中,没有任何个体可以继续前进。死锁不仅仅是在线程之会发生,存在资源独占的进程之间同样也可能出现死锁。通常来说,们大多是聚焦在多线程场景中的死锁,指两个或多个线程之间,由于相持有对方需要的锁,而永久处于阻塞的状态。你可以利用下面的示例图理解基本的死锁问题:定位死锁最常见的方式就是利用jstack等工具获取线程栈,然后定位互相之间的依赖关系,进而找到死锁。如果是比较明显的死锁,往往jstack等就能直接定位,类似JConsole甚至可以在图形界面进行有限的锁检测。如果程序运行时发生了死锁,绝大多数情况下都是无法在线解决的,能重启、修正程序本身问题。所以,代码开发阶段互相审查,或者利工具进行预防性排查,往往也是很重要的。考点分析今天的问题偏向于实用场景,大部分死锁本身并不难定位,掌握基本路和工具使用,理解线程相关的基本概念,比如各种线程状态和同步锁、Latch等并发工具,就已经足够解决大多数问题了。针对死锁,面试官可以深入考察:抛开字面上的概念,让面试者写一个可能死锁的程序,顺便也考下基本的线程编程。诊断死锁有哪些工具,如果是分布式环境,可能更关心能否用AP实现吗?后期诊断死锁还是挺痛苦的,经常加班,如何在编程中尽量避免些典型场景的死锁,有其他工具辅助吗?知识扩展在分析开始之前,先以一个基本的死锁程序为例,我在这里只用了两嵌套的synchronized去获取锁,具体如下:public class DeadLockSample extends Thread {private String first;private String second;public DeadLockSample(String name, String first, String secsuper(name);this.first = first;this.second = second;}public void run() {synchronized (first) {System.out.println(this.getName() + " obtained: " + try {Thread.sleep(1000L);synchronized (second) {System.out.println(this.getName() + " obtai}} catch (InterruptedException e) {// Do nothing}}}public static void main(String[] args) throws InterruptedExString lockA = "lockA";String lockB = "lockB";DeadLockSample t1 = new DeadLockSample("Thread1", lockADeadLockSample t2 = new DeadLockSample("Thread2", lockBt1.start();t2.start();t1.join();t2.join();}}这个程序编译执行后,几乎每次都可以重现死锁,请看下面截取的输出。另外,这里有个比较有意思的地方,为什么我先调用Thread1的start,但是Thread2却先打印出来了呢?这就是因为线程调度依赖于(作系统)调度器,虽然你可以通过优先级之类进行影响,但是具体情是不确定的。下面来模拟问题定位,我就选取最常见的jstack,其他一些类似JConso等图形化的工具,请自行查找。首先,可以使用jps或者系统的ps命令、任务管理器等工具,确定进程ID。其次,调用jstack获取线程栈:${JAVA_HOME}\bin\jstack your_pid然后,分析得到的输出,具体片段如下:最后,结合代码分析线程栈信息。上面这个输出非常明显,找到处于BLOCKED状态的线程,按照试图获取(waiting)的锁ID(请看我标记为相同颜色的数字)查找,很快就定位问题。 jstack本身也会把类似的简单死锁抽取出来,直接打印出来。在实际应用中,类死锁情况未必有如此清晰的输出,但是总体上可以解为:区分线程状态 -> 查看等待目标 -> 对比Monitor等持有状态所以,理解线程基本状态和并发相关元素是定位问题的关键,然后配程序调用栈结构,基本就可以定位到具体的问题代

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值