下面这段jstack的栈信息里,有一个死锁
其中:
Thread-1 持有 0x00000007d5df4970,等待获取:0x00000007d5df4960
Thread-0 持有 0x00000007d5df4960,等待获取:0x00000007d5df4970
所以导致了死锁的出现
两个线程都有有一句: java.lang.Thread.State: BLOCKED (on object monitor)
表明:两个线程都阻塞在了 对应正在操作对象的object monitor上(是因为对象 被另外一个线程获加锁成功,并占有object monitor)
那object monitor 和 lock 有什么关系和区别?
1、object monitor 是任何一个对象都有的内置的数据结构,它是用来协调使用当前对象的多个线程之间的执行顺序的(wait/notify),线程会block或者wait 在一个对象的监视器上;锁是 对对象访问的时候,通过对对象加锁,防止并行访问的控制手段;
2、对 对象加锁成功,才能拿到 object monitor (对象监视器),如果加锁失败,会进入对象监视器的entry队列里:(monitor entry list),表现为: waiting for monitor entry,java.lang.Thread.State: BLOCKED (on object monitor)
3、对 对象枷锁成功,调用wait方法,也会wait 在object monitor上,但是会释放锁,并进入(monitor wait list),当前线程也就WAITING (on object monitor),表现为:java.lang.Thread.State: WAITING (on object monitor) 一旦对象被调用notify的,会重新尝试加锁,成功可以执行,否则进入(monitor entry list)
4、锁和监视器的关系:拿到对象的监视器,肯定是对对象加锁成功的;对对象加锁成功 ,程序可以主动Watiing或者Time_waiting在对象监视器上
线程使用对象的方式:
1、直接使用,为了避免多个线程同时使用,需要加锁,加锁成功的可以使用对象;
2、需要对象到达某种状态才能用,这时候需要调用对象的wait方法,线程挂起(wait)在对象的object monitor 监视器上,等待其他线程notify,可能多个线程都在wait,所以notify的时候多个等待的线程需要再次获取锁 ,这就解释了为什么wait的时候需要先加锁,notify的时候也需要加锁成功
总结:
线程,对象,锁,监视器的关系:线程里可以定义并访问对象,为了访问的安全性,需要对对象加锁,如果加锁失败,线程就会block,并进入( waiting for monitor entry),如果加锁成功,可以选择直接执行逻辑,如果需要获取其他线程执行的结果,当前线程就需要挂起(调用wait方法),线程进入java.lang.Thread.State: WAITING (on object monitor)状态,此时线程会释放锁,同时进入到monitor entry list;如果其他线程执行完成后进行notify,当前线程也就需要再次获取锁,并获取 object monitor,开始执行
C:\Users\xinchun.wang>jstack 15416 2017-04-06 12:22:03 Full thread dump Java HotSpot(TM) 64-Bit Server VM (23.7-b01 mixed mode): "DestroyJavaVM" prio=6 tid=0x000000000057f000 nid=0x3e98 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Thread-1" prio=6 tid=0x000000000d8af000 nid=0x1d1c waiting for monitor entry [0x000000000ddae000] java.lang.Thread.State: BLOCKED (on object monitor) at Test$T2.run(Test.java:161) - waiting to lock <0x00000007d5df4960> (a java.lang.Object) - locked <0x00000007d5df4970> (a java.lang.Object) "Thread-0" prio=6 tid=0x000000000d8ae800 nid=0x790 waiting for monitor entry [0x000000000dcae000] java.lang.Thread.State: BLOCKED (on object monitor) at Test$T1.run(Test.java:136) - waiting to lock <0x00000007d5df4970> (a java.lang.Object) - locked <0x00000007d5df4960> (a java.lang.Object)
Found one Java-level deadlock: ============================= "Thread-1": waiting to lock monitor 0x000000000252ee70 (object 0x00000007d5df4960, a java.lang.Object), which is held by "Thread-0" "Thread-0": waiting to lock monitor 0x000000000252dac0 (object 0x00000007d5df4970, a java.lang.Object), which is held by "Thread-1" Java stack information for the threads listed above: =================================================== "Thread-1": at Test$T2.run(Test.java:161) - waiting to lock <0x00000007d5df4960> (a java.lang.Object) - locked <0x00000007d5df4970> (a java.lang.Object) "Thread-0": at Test$T1.run(Test.java:136) - waiting to lock <0x00000007d5df4970> (a java.lang.Object) - locked <0x00000007d5df4960> (a java.lang.Object)
相关推荐
3. 阻塞(BLOCKED):线程在等待监视器锁。 4. 等待(WAITING):线程在无限期等待另一个线程执行特定操作,如调用`wait()`方法。 5. 定时等待(TIMED_WAITING):线程在等待一定时间后被唤醒,例如`sleep()`或`join...
- `jconsole` 和 `jvisualvm`:提供图形界面来监视和分析JVM状态。 - `jmap`:内存映射工具,用于查看堆内存分配情况。 - `jhat`:分析堆转储文件。 - `jstack`:打印线程堆栈信息,排查死锁等问题。 - `-XX:+...
JVM(Java虚拟机)提供了多种监控工具来帮助开发者检测和解决这类问题。本篇将重点介绍几种常用的JVM监控工具,包括jstack、jconsole、jinfo、jmap以及jdb和jstat。 首先,`jstack`是一个用于打印Java线程堆栈跟踪...
`jstack` 是JDK自带的一个命令行工具,它能够打印出Java应用程序的线程堆栈信息,包括每个线程的当前状态、调用堆栈、锁定的监视器等。这对于排查线程问题非常有用。 ### 分析CPU占用过高 当Java应用的CPU占用率飙...
- JConsole:图形化监视和管理JVM。 - VisualVM:集成多种JVM分析工具,如内存分析、线程分析等。 - jinfo、jmap、jhat、jstack等命令行工具:用于查看JVM配置、内存映射、堆转储等。 通过学习《JVM基础-超清...
Java虚拟机(JVM)是Java程序运行的核心组件,它为开发者提供了跨平台的执行环境。深入理解JVM内核的原理、诊断与优化对于提升Java应用的性能至关重要。本教程将带你探索JVM的奥秘,从内存管理到垃圾回收,从编译...
以上介绍的各种JVM工具和参数对于Java开发人员来说是非常重要的,它们能够帮助我们更好地理解和管理JVM的行为,从而提高应用程序的性能和稳定性。在实际应用中,根据具体情况选择合适的工具和参数进行配置和调优是...
这个命令会自动下载并安装OpenJDK-7的deb包,包括Java编译器javac、Java解释器java以及相关的开发和运行库。安装完成后,可以通过`java -version`和`javac -version`命令来验证安装是否成功。 OpenJDK-7包含了以下...
- **JConsole**:提供GUI界面来监视JVM的性能和诊断问题。 - **JMX(Java Management Extensions)**:允许创建和注册MBeans来管理Java应用程序,可以远程监控和管理JVM。 4. **JVM参数调优**: - `-Xms` 和 `-...
jstat 是一个用于监视 JVM 内存使用情况的强大工具,它可以提供有关堆内存、非堆内存、类加载和垃圾收集器活动的详细信息。通过 jstat,你可以监控 JVM 各个区域的内存使用率,包括年轻代、老年代和永久代,这对于...
Java性能监视和管理官方指南涉及到Java平台标准版(Java Platform, Standard Edition, 简称Java SE)11版本中的监视和管理特性。这些特性允许程序员监控和管理Java程序的性能,并进行相应的优化。具体而言,这个官方...
- BLOCKED: 等待监视器锁。 - WAITING: 等待其他线程的动作,如调用notify()。 - TIMED_WAITING: 在等待一个具体的唤醒时间。 - TERMINATED: 已经完成执行。 **1.3 如何借助线程堆栈进行问题分析?** - **1.3.1 ...
它通过`monitorenter`和`monitorexit`指令实现,每个Java对象都有一个监视器(monitor)。当线程执行`monitorenter`时,它尝试获取对象锁,成功后执行代码块,执行完毕或遇到异常时执行`monitorexit`释放锁。 4. **...
- `BLOCKED`: 表示线程被阻塞,通常是等待获得监视器锁。 - `WAITING`: 线程处于无限期等待状态,通常是因为调用了`Object.wait()`方法。 - `TIMED_WAITING`: 线程处于有限期等待状态,如调用`Thread.sleep(long ...
- **BLOCKED**:线程在等待监视器锁。 - **WAITING**:线程在等待另一个线程执行特定操作,没有超时时间。 - **TIMED_WAITING**:线程在等待另一个线程执行操作,有设定的超时时间。 - **TERMINATED**:线程已...
### JVM概述 ...这显示了Java运行时环境的版本信息以及所使用的JVM的版本,对于确定Java环境配置和进行故障排查都非常重要。JVM的版本信息也能够帮助开发者了解所运行的应用程序所依赖的平台特性。
JVM(Java Virtual Machine)是 Java 语言的 Runtime 环境,它提供了多种命令来监控和管理 Java 应用程序的执行情况。在本文中,我们将介绍 10 个常见的 JVM 命令,包括 jps、jstat、jinfo、jmap 和 jstack 等。 ...
IBM Thread and Monitor Dump Analyzer是一款强大的工具,专门用于解析和分析javacore文件中的线程和监视器信息。通过该工具,我们可以: 1. **可视化线程图**:工具会生成一个清晰的线程树图,显示线程间的相互...