通过编程发现Java死锁
通过stack也可以发现死锁。
测试类
import java.util.concurrent.TimeUnit; public class Test {
public static void main(String[] args) {
DeadlockDetector deadlockDetector = new DeadlockDetector(new DeadlockConsoleHandler(), 5, TimeUnit.SECONDS);
deadlockDetector.start(); final Object lock1 = new Object();
final Object lock2 = new Object();
Thread thread1 = new Thread(()->{
synchronized (lock1) {
System.out.println("Thread1 acquired lock1");
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException ignore) {
}
synchronized (lock2) {
System.out.println("Thread1 acquired lock2");
}
}
});
thread1.start();
Thread thread2 = new Thread(()->{
synchronized (lock2) {
System.out.println("Thread2 acquired lock2");
synchronized (lock1) {
System.out.println("Thread2 acquired lock1");
}
}
});
thread2.start();
}
}
处理类
public class DeadlockConsoleHandler implements DeadlockHandler {
@Override
public void handleDeadlock(final ThreadInfo[] deadlockedThreads) {
if (deadlockedThreads != null) {
System.err.println("Deadlock detected!");
Map<Thread, StackTraceElement[]> stackTraceMap = Thread.getAllStackTraces();
for (ThreadInfo threadInfo : deadlockedThreads) {
if (threadInfo != null) {
for (Thread thread : Thread.getAllStackTraces().keySet()) {
if (thread.getId() == threadInfo.getThreadId()) {
System.err.println(threadInfo.toString().trim());
for (StackTraceElement ste : thread.getStackTrace()) {
System.err.println("t" + ste.toString().trim());
}
}
}
}
}
}
}
}
import java.lang.management.ThreadInfo;
public interface DeadlockHandler {
void handleDeadlock(final ThreadInfo[] deadlockedThreads);
}
关键类
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; public class DeadlockDetector { private final DeadlockHandler deadlockHandler;
private final long period;
private final TimeUnit unit;
private final ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); final Runnable deadlockCheck = new Runnable() {
@Override
public void run() {
long[] deadlockedThreadIds = mbean.findDeadlockedThreads();
if (deadlockedThreadIds != null) {
ThreadInfo[] threadInfos = mbean.getThreadInfo(deadlockedThreadIds);
deadlockHandler.handleDeadlock(threadInfos);
}
}
}; public DeadlockDetector(final DeadlockHandler deadlockHandler, final long period, final TimeUnit unit) {
this.deadlockHandler = deadlockHandler;
this.period = period;
this.unit = unit;
} public void start() {
this.scheduler.scheduleAtFixedRate(this.deadlockCheck, this.period, this.period, this.unit);
}
}
测试结果
Thread1 acquired lock1
Thread2 acquired lock2
Deadlock detected!
"Thread-1" Id=12 BLOCKED on java.lang.Object@6a80bb83 owned by "Thread-0" Id=11
ttest.Test.lambda$main$1(Test.java:32)
ttest.Test$$Lambda$2/363771819.run(Unknown Source)
tjava.lang.Thread.run(Thread.java:745)
"Thread-0" Id=11 BLOCKED on java.lang.Object@6ebf220b owned by "Thread-1" Id=12
ttest.Test.lambda$main$0(Test.java:23)
ttest.Test$$Lambda$1/668386784.run(Unknown Source)
tjava.lang.Thread.run(Thread.java:745)
Deadlock detected!
通过编程发现Java死锁的更多相关文章
- 如何通过编程发现Java死锁
本文由 ImportNew - rookie_sam 翻译自 Dzone.欢迎加入翻译小组.转载请见文末要求. 死锁是指,两个或多个动作一直在等待其他动作完成而使得所有动作都始终处在阻塞的状态.想要在 ...
- Java并发编程实战 04死锁了怎么办?
Java并发编程文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 Java并发编程实战 03互斥锁 解决原子性问题 前提 在第三篇 ...
- Java多线程编程(同步、死锁、生产消费者问题)
Java多线程编程(同步.死锁.生产消费): 关于线程同步以及死锁问题: 线程同步概念:是指若干个线程对象并行进行资源的访问时实现的资源处理保护操作: 线程死锁概念:是指两个线程都在等待对方先完成,造 ...
- java 死锁及解决
Java线程死锁如何避免这一悲剧 Java线程死锁需要如何解决,这个问题一直在我们不断的使用中需要只有不断的关键.不幸的是,使用上锁会带来其他问题.让我们来看一些常见问题以及相应的解决方法: Jav ...
- Java死锁及解决
Java线程死锁如何避免这一悲剧 Java线程死锁需要如何解决,这个问题一直在我们不断的使用中需要只有不断的关键.不幸的是,使用上锁会带来其他问题.让我们来看一些常见问题以及相应的解决方法: Jav ...
- 一文学会Java死锁和CPU 100% 问题的排查技巧
做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开 工欲善其事,必先利其器 00 本文简介 作为一名搞技术的程序猿或者是攻城狮,想必你应该是对下面这两个问题有所了解,说不定你在 ...
- 实例详解 Java 死锁与破解死锁
锁和被保护资源之间的关系 我们把一段需要互斥执行的代码称为临界区.线程在进入临界区之前,首先尝试加锁 lock(),如果成功,则进入临界区,此时我们称这个线程持有锁:否则呢就等待,直到持有锁的线程解锁 ...
- 为什么函数式编程在Java中很危险?
摘要:函数式编程这个不温不火的语言由来已久.有人说,这一年它会很火,尽管它很难,这也正是你需要学习的理由.那么,为什么函数式编程在Java中很危险呢?也许这个疑问普遍存在于很多程序员的脑中,作者Ell ...
- Java并发编程:Java的四种线程池的使用,以及自定义线程工厂
目录 引言 四种线程池 newCachedThreadPool:可缓存的线程池 newFixedThreadPool:定长线程池 newSingleThreadExecutor:单线程线程池 newS ...
随机推荐
- 屏幕截图、录像FastStone Capture
作为一款极其优秀好用的屏幕截图软件,FastStone Capture 具有体积小巧.功能强大.操作简便等优点,其方便的浮动工具条和便捷的快捷键堪称完美结合,截图后的图片编辑与保存选项也特别丰富和方便 ...
- 使用CSS中margin和padding的基础和注意事项
在CSS中,margin和padding是页面布局的主要属性,如何灵活有效使用对于基于DIV+CSS设计网页方法是非常重要的,笔者经常使用且经常误使用,所以根据经验和网上资料整理出切合自己的内容,以备 ...
- ios 宏定义 系统版本 判定
当需要判断iOS系统版本的时候,相信很多人都会这么干: #define SystemVersion [[UIDevice currentDevice] systemVersion].floatValu ...
- python学习 小游戏
基于python3.4 while循环 #!/usr/bin/python3 #-*- coding=utf-8 -*- import random import sys import os luck ...
- 解决webstorm乱码
新的web前端学习群,120342833,欢迎大家一起学习,以前在web学习群里的看到了加下..
- Java大数处理类:BigInteger类和BigDecimal类
当我们要处理非常大的数据时,平常用的数据类型已不足以表示,在Java中有两个类BigInteger和BigDecimal分别表示大整数类和大浮点数类,这两个类在理论上只要计算机内存足够大就能够表示无线 ...
- Xcode常用代码块
Xcode的代码片段(Code Snippets)创建自定义的代码片段,当你重用这些代码片段时,会给你带来很大的方便. 常用的: 1.strong:@property (nonatomic,stron ...
- Django搭建简易博客
Django简易博客,主要实现了以下功能 连接数据库 创建超级用户与后台管理 利用django-admin-bootstrap美化界面 template,view与动态URL 多说评论功能 Markd ...
- Mac系统下使用VirtualBox虚拟机安装win7--第三步 在虚拟机上安装 Windows 7
第三步 在虚拟机上安装 Windows 7 等待虚拟机进入 Windows 7 的安装界面以后,在语言,货币,键盘输入法这一面,建议保持默认设置,直接点击“下一步”按钮,如图所示
- 三、jQuery--jQuery基础--jQuery基础课程--第3章 jQuery过滤性选择器
1.:first过滤选择器 本章我们介绍过滤选择器,该类型的选择器是根据某过滤规则进行元素的匹配,书写时以“:”号开头,通常用于查找集合元素中的某一位置的单个元素. 在jQuery中,如果想得到一组相 ...