什么情况下Java程序会产生死锁?如何定位和修复死锁_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 什么情况下Java程序会产生死锁?如何定位和修复死锁

什么情况下Java程序会产生死锁?如何定位和修复死锁

 2019/4/18 21:45:27  hbxflihua  程序员俱乐部  我要评论(0)
  • 摘要:死锁是一种特定的程序状态,在实体之间,由于循环依赖导致彼此一直处于等待之中,没有任何个体可以继续前进。死锁不仅仅是在线程之间会发生,存在资源独占的进程之间同样也可能出现死锁。通常来说,我们大多是聚焦在多线程场景中的死锁,指两个或多个线程之间,由于相互持有对方需要的锁,而永久处于阻塞的状态。定位死锁最常见的方式就是利用jstack等工具获取线程栈,然后定位相互之间的依赖关系,进而找到死锁。如果是比较明显的死锁,往往jstack等就能直接定位
  • 标签:程序 情况 Java 什么 生死 修复 定位

class="MsoNormal">死锁是一种特定的程序状态,在实体之间,由于循环依赖导致彼此一直处于等待之中,没有任何个体可以继续前进。死锁不仅仅是在线程之间会发生,存在资源独占的进程之间同样也可能出现死锁。通常来说,我们大多是聚焦在多线程场景中的死锁,指两个或多个线程之间,由于相互持有对方需要的锁,而永久处于阻塞的状态。

?

定位死锁最常见的方式就是利用jstack等工具获取线程栈,然后定位相互之间的依赖关系,进而找到死锁。如果是比较明显的死锁,往往jstack等就能直接定位,类似jconsole甚至可以在图形界面进行有限的死锁检测。

?

如果程序运行时发生了死锁,绝大多数情况下都是无法在线解决的,只能重启、修正程序本身的问题。所以,代码开发阶段玄乎审查,或者利用工具进行预防性排查,往往也是很重要的。

?

Java提供了标准的管理API-ThreadMXBean来进行死锁的定位跟踪,示例代码如下:

?

public static void main(String[] args) throws InterruptedException {

	ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
	Runnable dlCheck = new Runnable() {

 ???	@Override
 ???	public void run() {
 ???????	long[] threadIds = mbean.findDeadlockedThreads();
 ???????	if (threadIds != null) {
 ????????????????????ThreadInfo[] threadInfos = mbean.getThreadInfo(threadIds);
 ????????????????????System.out.println("Detected deadlock threads:");
 ???????????	for (ThreadInfo threadInfo : threadInfos) {
 ???????????????	System.out.println(threadInfo.getThreadName());
 ???????????	}
 ?????????}
 ??????}
 ???};

 ??????ScheduledExecutorService scheduler =Executors.newScheduledThreadPool(1);
 ??????// 稍等 5 秒,然后每 10 秒进行一次死锁扫描
 ???????scheduler.scheduleAtFixedRate(dlCheck, 5L, 10L, TimeUnit.SECONDS);
// 死锁样例代码…
}

?

?需要注意的是,对线程进行快照本身是一个相对重量级的操作,需要慎重选择频度和时机。

?

如何在程序中尽量避免死锁?

1、如果可能,尽量避免使用多个锁,并且只有在需要时才持有锁,嵌套synchronizedlock很容易产生死锁。

2、如果必须使用多个锁,尽量设计好锁的获取顺序。

3、使用带超时的方法,为程序带来更多的可控性。

上一篇: C# 在PDF中添加不同类型的注释(5种) 下一篇: 没有下一篇了!
发表评论
用户名: 匿名