例子程序:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Hello world!
*/
public class App {
public static void main(String[] args) throws InterruptedException {
System.out.println("Hello World!");
ExecutorService executorService = Executors.newFixedThreadPool(2);
byte[] i = new byte[0];
byte[] j = new byte[0];
final CountDownLatch countDownLatch = new CountDownLatch(2);
executorService.execute(new DeadThread1(i, j,countDownLatch));
executorService.execute(new DeadThread2(i, j,countDownLatch));
countDownLatch.await();
System.out.println("done !!!");
}
public static class DeadThread1 implements Runnable {
private byte[] i;
private byte[] j;
private CountDownLatch countDownLatch;
public DeadThread1(byte[] i, byte[] j, CountDownLatch countDownLatch) {
this.i = i;
this.j = j;
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
synchronized (i) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (j) {
System.out.println(Thread.currentThread().getName() + "is running!!");
countDownLatch.countDown();
}
}
}
}
public static class DeadThread2 implements Runnable {
private byte[] i;
private byte[] j;
private CountDownLatch countDownLatch;
public DeadThread2(byte[] i, byte[] j, CountDownLatch countDownLatch) {
this.i = i;
this.j = j;
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
synchronized (j) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (i) {
System.out.println(Thread.currentThread().getName() + "is running!!");
countDownLatch.countDown();
}
}
}
}
}
通过jps找到当前进程号:
guohaozhao116008@GUOHAOZHAO11600 /d
$ jps
7448 RemoteMavenServer
6600 JConsole
6340 Jps
6272
7268 AppMain
通过jstack查看堆栈信息:
guohaozhao116008@GUOHAOZHAO11600 /d
$ jstack
Usage:
jstack [-l] <pid>
(to connect to running process)
jstack -F [-m] [-l] <pid>
(to connect to a hung process)
jstack [-m] [-l] <executable> <core>
(to connect to a core file)
jstack [-m] [-l] [server_id@]<remote server IP or hostname>
(to connect to a remote debug server)
Options:
-F to force a thread dump. Use when jstack <pid> does not respond (process is hung)
-m to print both java and native frames (mixed mode)
-l long listing. Prints additional information about locks
-h or -help to print this help message
guohaozhao116008@GUOHAOZHAO11600 /d
$ jps
7448 RemoteMavenServer
6600 JConsole
6340 Jps
6272
7268 AppMain
guohaozhao116008@GUOHAOZHAO11600 /d
$ jstack -l 7268
2013-05-30 18:36:41
Full thread dump Java HotSpot(TM) 64-Bit Server VM (20.14-b01 mixed mode):
Found one Java-level deadlock:
=============================
"pool-1-thread-2":
waiting to lock monitor 0x000000000677c208 (object 0x00000000eafc3e18, a [B),
which is held by "pool-1-thread-1"
"pool-1-thread-1":
waiting to lock monitor 0x0000000006771be8 (object 0x00000000eafc3e28, a [B),
which is held by "pool-1-thread-2"
Java stack information for the threads listed above:
===================================================
"pool-1-thread-2":
at com.sohu.suc.App$DeadThread2.run(App.java:74)
- waiting to lock <0x00000000eafc3e18> (a [B)
- locked <0x00000000eafc3e28> (a [B)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)
"pool-1-thread-1":
at com.sohu.suc.App$DeadThread1.run(App.java:45)
- waiting to lock <0x00000000eafc3e28> (a [B)
- locked <0x00000000eafc3e18> (a [B)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at java.lang.Thread.run(Thread.java:662)
Found 1 deadlock.
可以看到:
这里发生了死锁。
使用图形工具 jconsole 同样可以检测到:
- 大小: 64.2 KB
分享到:
相关推荐
在实际应用中,使用Lookcop进行线程死锁检测可以分为以下步骤: 1. **集成Lookcop**:将Lookcop工具引入到项目中,这通常可以通过添加依赖或插件实现,确保在运行时能启动死锁检测。 2. **配置与参数**:根据项目...
Java线程死锁是多线程编程中一个常见的问题,它发生在两个或多个线程相互等待对方释放资源,导致它们都无法继续执行的情况。死锁的发生通常涉及到四个必要条件:互斥、请求与保持、不剥夺和循环等待。理解并解决Java...
Java 线程死锁的问题解决办法 Java 线程死锁是指两个或两个以上的线程在执行过程中,相互等待对方释放资源,从而造成的僵持状态。在 Java 中,线程死锁的问题解决办法是非常重要的,下面我们将深入探讨 Java 线程...
java线程死锁代码示例 本文主要介绍了java线程死锁代码示例,分享了一个简单线程死锁的例子,需要的朋友可以参考下。以下是对该示例的详细解释和知识点总结: 1. 死锁的概念:死锁是操作系统层面的一个错误,是...
在Java应用程序的运行过程中,了解线程的状态和行为至关重要,因为这可以帮助我们诊断性能问题、内存泄漏或死锁。本文将深入探讨如何使用Java提供的工具——`jps`和`jstack`,以及如何通过Shell脚本来定时收集Java...
除了JCarder,Java还提供了其他的死锁检测工具和手段,如JConsole、VisualVM和JDK自带的jstack命令。这些工具都可以帮助我们分析线程状态,找出可能导致死锁的原因。 在编写多线程程序时,预防死锁的一些最佳实践...
本主题将深入探讨死锁的概念、死锁的四个必要条件以及如何在Java中实现死锁检测。 死锁的定义: 死锁是指系统中的多个进程相互等待对方释放资源,从而陷入无法前进的状态。这种状态通常会导致系统停滞不前,影响...
《JAVA线程(第三版)》是一本深入探讨Java多线程编程的权威书籍,针对Java线程的管理和优化提供了详尽的解析。线程在现代计算机编程中扮演着至关重要的角色,尤其是在并发处理和高性能应用中。Java以其强大的线程...
5. 使用死锁检测工具(如Java的jconsole或VisualVM),监控并分析程序中的死锁情况。 了解并掌握这些预防死锁的策略,可以显著提高多线程程序的稳定性和效率。在实际开发中,我们需要时刻警惕死锁的可能性,通过...
- **死锁检测**:自动检测并标记出可能存在的死锁情况,帮助开发者快速定位问题。 - **线程持有锁分析**:列出线程持有的锁信息,帮助找出导致阻塞的原因。 - **线程堆栈深度查看**:可以查看每个线程的调用堆栈,...
4. 检测和恢复:使用Java的`java.util.concurrent.locks.Condition`类提供的方法,检测是否可能出现死锁,并在检测到时进行恢复操作。 5. 避免持有多个资源时请求新资源:如果一个线程已经持有了一些资源,应避免在...
JCarder是一个Java线程分析工具,它能够帮助开发者识别和定位多线程程序中的死锁、活锁和饥饿等问题。通过分析线程间的锁获取和释放顺序,JCarder可以检测出可能导致死锁的潜在模式,从而提高程序的健壮性和可靠性。...
- **死锁检测与恢复**:使用Java 1.6及以上版本提供的`java.util.concurrent.locks.Condition`类,可以实现检测到死锁后进行恢复的操作。 - **资源排序**:确保所有线程都按照同一顺序请求资源,可以避免死锁。 6...
要检测和避免死锁,Java提供了一些工具。`jstack`命令可以输出线程堆栈信息,帮助我们分析是否存在死锁状态。此外,`java.util.concurrent.locks.Condition`接口提供了更灵活的同步机制,可以用于精细控制线程的等待...
在Java编程中,死锁是并发编程中一个重要的概念,它发生在两个或多个线程相互等待对方释放资源,导致它们都无法继续执行的情况。这个例子中,我们将会深入探讨死锁的产生、识别以及如何避免它。 首先,让我们理解...
5. **JCarder工具**:`JCarder`是一个专门针对Java多线程死锁的检测工具,它通过分析线程的同步状态和资源持有情况,找出可能存在的死锁链。 三、JCarder的使用与原理 6. **使用方法**:首先,将`JCarder`工具集成...
避免死锁的方法包括资源预分配、避免循环等待和使用死锁检测算法。 Java线程实例通常包括生产者消费者模型、哲学家就餐问题、银行家算法等经典案例,这些实例有助于理解线程的同步、协作和资源管理。 总结来说,...
Java多线程死锁是并发编程中一个严重的问题,它发生在两个或更多个线程相互等待对方持有的资源而无法继续执行的情况。理解死锁的概念及其产生原因对于避免和解决这类问题至关重要。 首先,死锁产生的主要原因包括:...
3. **死锁检测**:JCarder会持续监控程序运行中的线程状态和锁的获取与释放情况。当检测到有线程因为资源竞争进入死锁状态时,它会输出详细的死锁链信息,包括涉及的线程、持有的锁以及等待的锁。 4. **分析结果**...