Java多线程编程也是Java面试中经常考察的内容。刚接触Java多线程编程的朋友们,可能会不慎写出一些会导致死锁(deadlock)的应用出来。如何分析造成Java多线程的原因呢?很多时候我们在怀疑造成死锁的语句设置断点,单步调试,反而又不能重现了。这种现象很正常,因为咱们单步调试和直接运行程序,代码执行的时序是不同的,很可能无法满足死锁的触发条件。
实际上,JDK已经给Java程序员提供了强大的死锁分析工具,能够直接分析一个正在运行的并且处于死锁状态的应用,并给出具体是哪一行Java代码引起的死锁。
这篇文章就以一个例子来给大家演示如何使用这个JDK提供的标准工具。
这个工具叫jstack,就是JDK安装目录的bin文件夹下的一个执行文件。
我们首先写一个会导致死锁的应用出来。
public class DeadLockExample {
public static void main(String[] args) {
final String resource1 = "ABAP";
final String resource2 = "Java";
Thread t1 = new Thread() {
public void run() {
synchronized (resource1) {
System.out.println("Thread 1: locked resource 1");
try {
Thread.sleep(100);
}
catch (Exception e) {
}
synchronized (resource2) {
System.out.println("Thread 1: locked resource 2");
}
}
}
}
;
Thread t2 = new Thread() {
public void run() {
synchronized (resource2) {
System.out.println("Thread 2: locked resource 2");
try {
Thread.sleep(100);
}
catch (Exception e) {
}
synchronized (resource1) {
System.out.println("Thread 2: locked resource 1");
}
}
}
}
;
t1.start();
t2.start();
}
}
这个应用思路很简单,同时启动两个线程,分别锁住了resource1和resource2,然后休眠0.1秒,接着分别尝试去请求资源resource2和resource1。
执行应用,在控制台打印出下列输出后,进入死锁状态:
Thread 1: locked resource 1
Thread 2: locked resource 2
使用命令行 jps -l -m找到处于死锁状态应用的进程id。从下图得知死锁进程为51476:
然后使用命令行jstack 51476打印这个进程的运行栈信息。
我上图红色高亮出的 0x00000000d6f64988 和 0x00000000d6f649b8代表了代码中的两个资源“ABAP” 和“Java”。
jstack打印的输出非常清晰,显示了具体哪行Java代码试图去锁定哪一个Java资源(下图的waiting to lock)但是没有成功, 并且将失败的原因,即拥有当前请求资源的线程名称也打印了出来。
有了jstack,Java程序员不用对着冗长烧脑的多线程代码去冥思苦想了,JDK会自动把死锁原因打印出来,太方便了。
要获取更多Jerry的原创技术文章,请关注公众号"汪子熙"或者扫描下面二维码:
相关推荐
标题中的“图形界面分析threadump_jstack分析工具_包含jdk”指的是一个专用于分析Java应用程序线程堆栈信息的工具,该工具具有图形用户界面,能够帮助开发者更直观地理解和解决程序中的线程问题。这个工具包含了JDK...
在Java开发过程中,JDK提供...在实际开发和维护中,熟练掌握这些JDK自带的调试工具,不仅可以帮助我们找出代码中的问题,还可以优化应用性能,提升软件质量。因此,理解并运用这些工具是每个Java开发者必备的技能之一。
7. **jhat**:Java堆分析工具,与jmap配合使用,可以分析堆转储文件,找出内存泄漏等问题。 8. **jstack**:线程堆栈跟踪工具,可以查看Java应用的线程状态,帮助定位死锁或阻塞问题。 9. **jinfo**:配置信息显示...
除了JCarder,Java还提供了其他的死锁检测工具和手段,如JConsole、VisualVM和JDK自带的jstack命令。这些工具都可以帮助我们分析线程状态,找出可能导致死锁的原因。 在编写多线程程序时,预防死锁的一些最佳实践...
`JStack`是Java Development Kit (JDK)的一部分,用于生成正在运行的Java应用程序的线程快照。这些快照提供了关于每个线程正在做什么以及它们所处的状态等信息。这对于诊断线程挂起、死锁和其他多线程问题非常有用。...
Java JDK(Java Development Kit)是Java编程语言的核心组件,它包含了一整套用于开发和运行Java应用程序的工具。这个压缩包文件"java jdk"很可能包含了JDK的完整安装包或者帮助文档,对于学习和理解Java语言至关...
JDK(Java Development Kit)作为Java编程语言的核心组件,不仅提供了必要的编译、调试及文档工具,还配备了一系列用于监控和诊断应用程序运行状态的工具。本文将详细介绍这些工具的功能与应用场景,并通过具体的...
Jstack是Java开发工具包(JDK)中自带的一个命令行工具,它用于生成Java虚拟机(JVM)当前时刻的线程快照。线程快照中包含了JVM内所有线程的堆栈跟踪信息,是进行问题定位和性能调优时不可或缺的资源。Jstack可以...
jstack是Java开发工具包(JDK)中的一款命令行工具,用于生成Java虚拟机(JVM)当前时刻的线程堆栈跟踪信息。它可以帮助开发者查看线程的状态,定位程序的死锁、阻塞等问题,从而辅助诊断和优化Java应用程序的性能。...
VisualVM是一款强大的Java应用程序性能分析工具,它是JDK自带的一部分,可以用来监控和诊断Java应用程序。VisualVM提供了丰富的功能,包括内存分析、线程检查、CPU使用率监测、类加载和垃圾收集信息等,帮助开发者...
JDK14中性能管理工具之一的jstack,其主要功能是打印Java虚拟机(JVM)中的线程堆栈信息。该功能对于性能分析、问题诊断和调试都非常重要,尤其是在处理死锁、性能瓶颈或系统崩溃等异常情况时。jstack能够提供关于线程...
本篇文章将详细介绍Java开发工具包(JDK)中的一些重要监控和故障处理工具,这些工具可以帮助开发者识别和解决生产环境中的内存溢出问题,进而提升应用程序的性能和稳定性。 首先,我们来了解JDK提供的几个监控和...
总之,jstack是一个非常强大的工具,通过它可以有效诊断和解决Java程序中的线程相关问题,例如线程阻塞或死锁。熟练掌握jstack的使用对于任何Java应用程序的性能优化和问题解决都有着重要作用。
在介绍如何使用jstack分析并解决Java进程中的死锁问题之前,我们首先需要了解什么是死锁以及它为何会在多线程程序中发生。在多线程环境中,当两个或多个线程在执行过程中因争夺资源而造成相互等待,这种状态被称为...
Java开发工具包(Java Development Kit,简称JDK)是Oracle公司提供的用于开发和运行Java应用程序的软件包。它是Java程序员的基础工具,包含了编译、调试、文档生成等所需的组件和库。在本压缩包"jdk安装包-java开发...
Java Development Kit(JDK)是Java编程语言的核心组件,它为开发者提供了编译、调试和运行Java应用程序所需的所有工具。"jdk-8u301-windows-x64.rar" 是一个针对Windows 64位操作系统的JDK 1.8更新301的压缩包文件...
`jstack` 是JDK自带的一个命令行工具,它能够打印出Java应用程序的线程堆栈信息,包括每个线程的当前状态、调用堆栈、锁定的监视器等。这对于排查线程问题非常有用。 ### 分析CPU占用过高 当Java应用的CPU占用率飙...
Java Development Kit(JDK)是Java编程语言的核心组件,它为开发者提供了编译、调试和运行Java应用程序所需的所有工具。JDK8是Oracle公司发布的Java 8版本,它引入了许多新特性和改进,使得开发更加高效和简洁。在...
Java Development Kit(JDK)是Java编程语言的核心组件,它为开发者提供了编译、调试和运行Java应用程序所需的所有工具。JDK-1.7免安装版本,正如其名,是一种无需通过传统安装过程就能使用的JDK版本。这种设计极大...