`

java-jvm-jstack-线程状态

阅读更多

常见的线程状态:

RUNNABLE:正在执行的线程

注意:这里执行是针对jvm来说的,并非真的在cpu上执行,这要看操作系统处理器是否有机会

 

 

BLOCKED:阻塞的线程

注意:阻塞的线程一般是拿不到监视器锁(a monitor lock),比如:synchronized block/method,ReentrantLock.lock()

 

jstack一般显示为:

"Thread-0" prio=6 tid=0x000000000b67f800 nid=0x40d0 waiting on condition [0x000000000da7f000]

   java.lang.Thread.State: TIMED_WAITING (sleeping)

        at java.lang.Thread.sleep(Native Method)

        at Test$1.run(Test.java:26)

        - locked <0x00000007d5df43f8> (a java.util.HashMap)

 

"main" prio=6 tid=0x00000000021cf000 nid=0x1870 waiting for monitor entry [0x000000000262f000]

   java.lang.Thread.State: BLOCKED (on object monitor)

        at Test.test1(Test.java:39)

        - waiting to lock <0x00000007d5df43f8> (a java.util.HashMap)

        at Test.main(Test.java:7)

 

分析:

Thread-0:

1、拿到了锁并且没有释放:locked <0x00000007d5df43f8> (a java.util.HashMap)

2、线程调用了sleep方法,java.lang.Thread.State: TIMED_WAITING (sleeping)      

 

main线程:

1、java.lang.Thread.State: BLOCKED (on object monitor):因为锁被Thread-0 占用,拿不到锁( waiting for monitor entry),进入 BLOCKED 状态

2、waiting to lock <0x00000007d5df43f8> (a java.util.HashMap):首先锁的编号是:0x00000007d5df43f8,锁的对象是HashMap (a java.util.HashMap)

 

总结:

1、这种方式可以轻松分析出来 BLOCKED 的线程是被那个锁阻塞的

2、从代码的输出可以看出:线程Thread-0 持有锁,进入sleep后,不会释放锁,否则main线程的(##############) 会输出    

3、echo "obase=10;ibase=16;40D0"|bc   ; 输出为:16592,可以定位线程id   

java 代码为:

private  static void test1() throws Exception {
		final Map<String, User> map = new HashMap<String, User>();
		new Thread() {
			@Override
			public void run() {
				synchronized (map) {
					try {
						System.out.println("***************");
						
						System.out.println("map: " +Long.toHexString(map.hashCode()));
						System.out.println("map: " +(map));
						System.out.println("newThread: " +(Thread.currentThread().getId()));
						System.out.println("newThread: " +Long.toHexString(Thread.currentThread().getId()));
						System.out.println("newThread: " +Long.toHexString(Thread.currentThread().hashCode()));
						
						Thread.sleep(10000000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}.start();

		Thread.sleep(10000);
		System.out.println("mainThread: " +(Thread.currentThread().getId()));
		System.out.println("mainThread: " +Long.toHexString(Thread.currentThread().getId()));
		System.out.println("mainThread: " +Long.toHexString(Thread.currentThread().hashCode()));
		synchronized (map) {
			System.out.println("##############");
			map.wait();
		}

		int i = 0;
		while (true) {
			map.put("value" + i, new User(i));
			i++;
			if (map.size() > 1000000) {
				map.clear();
			}
		}
	
	}

 

 

输出:

***************

map: 0

map: {}

newThread: 9

newThread: 9

newThread: 64afb650

mainThread: 1

mainThread: 1

mainThread: 138b9a72

 

 

WAITING:等待状态

一般以下三种调用:

Object.wait with no timeout 

Thread.join with no timeout 

LockSupport.park 

 

jstack一般显示为:

"Thread-0" prio=6 tid=0x000000000d447000 nid=0x31b8 in Object.wait() [0x000000000da8f000]

   java.lang.Thread.State: WAITING (on object monitor)

        at java.lang.Object.wait(Native Method)

        - waiting on <0x00000007d5df43f8> (a java.util.HashMap)

        at java.lang.Object.wait(Object.java:503)

        at Test$2.run(Test.java:65)

        - locked <0x00000007d5df43f8> (a java.util.HashMap)

 

"main" prio=6 tid=0x000000000238f000 nid=0x372c in Object.wait() [0x000000000279f000]

   java.lang.Thread.State: WAITING (on object monitor)

        at java.lang.Object.wait(Native Method)

        - waiting on <0x00000007d5df43f8> (a java.util.HashMap)

        at java.lang.Object.wait(Object.java:503)

        at Test.test2(Test.java:78)

        - locked <0x00000007d5df43f8> (a java.util.HashMap)

        at Test.main(Test.java:7)

        

分析:

1、Thread-0 和 main 线程 都是因为调用 wait() 方法 进入阻塞的

2、他们都拿到了锁:locked <0x00000007d5df43f8> (a java.util.HashMap)

3、java.lang.Thread.State: WAITING (on object monitor):他们都在等待 对象监视器(on object monitor)的通知

4、从代码的输出可以看出:线程进入wait后,会释放锁,否则(##############) 不会输出

5、0x000000000da8f000,0x000000000279f000 的值的含义为:线程的起始栈地址

 

 

java代码:

private  static void test2() throws Exception {
		final Map<String, User> map = new HashMap<String, User>();
		new Thread() {
			@Override
			public void run() {
				synchronized (map) {
					try {
						System.out.println("***************");
						System.out.println("newThread: " +Long.toHexString(Thread.currentThread().getId()));
						System.out.println("newThread: " +Long.toHexString(Thread.currentThread().hashCode()));
						
						map.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}.start();

		Thread.sleep(10000);
		System.out.println("mainThread: " +Long.toHexString(Thread.currentThread().getId()));
		System.out.println("mainThread: " +Long.toHexString(Thread.currentThread().hashCode()));
		synchronized (map) {
			System.out.println("##############");
			map.wait();
		}

		int i = 0;
		while (true) {
			map.put("value" + i, new User(i));
			i++;
			if (map.size() > 1000000) {
				map.clear();
			}
		}
	
	}

 

输出:

***************

newThread: 9

newThread: 517c804b

mainThread: 1

mainThread: 138b9a72

##############

 

 

TIMED_WAITING:等待特定时间

情况分析(Block的时候已经有说明)

Thread.sleep 

Object.wait with timeout 

Thread.join with timeout 

LockSupport.parkNanos 

LockSupport.parkUntil 

 

jvm的线程的状态定义如下:

 

public enum State {
        /**
         * Thread state for a thread which has not yet started.
         */
        NEW,

        /**
         * Thread state for a runnable thread.  A thread in the runnable
         * state is executing in the Java virtual machine but it may
         * be waiting for other resources from the operating system
         * such as processor.
         */
        RUNNABLE,

        /**
         * Thread state for a thread blocked waiting for a monitor lock.
         * A thread in the blocked state is waiting for a monitor lock
         * to enter a synchronized block/method or
         * reenter a synchronized block/method after calling
         * {@link Object#wait() Object.wait}.
         */
        BLOCKED,

        /**
         * Thread state for a waiting thread.
         * A thread is in the waiting state due to calling one of the
         * following methods:
         * <ul>
         *   <li>{@link Object#wait() Object.wait} with no timeout</li>
         *   <li>{@link #join() Thread.join} with no timeout</li>
         *   <li>{@link LockSupport#park() LockSupport.park}</li>
         * </ul>
         *
         * <p>A thread in the waiting state is waiting for another thread to
         * perform a particular action.
         *
         * For example, a thread that has called <tt>Object.wait()</tt>
         * on an object is waiting for another thread to call
         * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
         * that object. A thread that has called <tt>Thread.join()</tt>
         * is waiting for a specified thread to terminate.
         */
        WAITING,

        /**
         * Thread state for a waiting thread with a specified waiting time.
         * A thread is in the timed waiting state due to calling one of
         * the following methods with a specified positive waiting time:
         * <ul>
         *   <li>{@link #sleep Thread.sleep}</li>
         *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
         *   <li>{@link #join(long) Thread.join} with timeout</li>
         *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
         *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
         * </ul>
         */
        TIMED_WAITING,

        /**
         * Thread state for a terminated thread.
         * The thread has completed execution.
         */
        TERMINATED;
    }

 

0
0
分享到:
评论

相关推荐

    java 查看JVM中所有的线程的活动状况

    在Java编程环境中,了解JVM(Java虚拟机)中所有线程的活动状态对于调试多线程程序至关重要。本文将详细讲解如何查看JVM中的线程活动情况,并提供相关示例代码。 首先,Java提供了`java.lang.management....

    show-busy-java-threads-jvm-cpu.rar

    `show-busy-java-threads.sh` 脚本的原理是利用JVM提供的命令行工具,如`jstack`(Java堆栈跟踪),来获取当前JVM中线程的详细信息。`jstack`命令可以打印出Java应用程序的线程快照,包括每个线程的ID、状态、调用...

    java-JVM-面试题从基础到高级详解-HM

    2. **JDK自带工具**:如jconsole、jvisualvm用于监控JVM状态,jmap用于内存映射,jstack用于线程堆栈快照,jhat用于堆转储分析。 五、JVM与其他技术的交互 1. **JNI(Java Native Interface)**:允许Java代码调用...

    show-busy-java-threads.sh文件

    `show-busy-java-threads.sh`脚本通过JVM提供的命令行工具`jstack`来获取当前Java进程的线程堆栈信息,从而揭示这些繁忙线程的详细状态。 `jstack`是Java标准工具包(JDK)的一部分,它能输出Java虚拟机(JVM)中...

    Java虚拟机-jvm故障诊断与性能优化-源码

    - **线程dump**:jstack命令获取线程状态,排查死锁、阻塞等问题。 - **日志分析**:JVM会生成各种日志,如gc.log,用于分析垃圾收集行为。 6. **性能瓶颈识别** - **CPU耗时分析**:找出消耗CPU最多的代码段。 ...

    JAVA命令大全-JVM设置.rar

    4. **JVM诊断**:`jinfo`显示JVM配置信息,`jstack`打印线程堆栈跟踪,`jcmd`执行JVM命令,`jdiag`(在某些JDK版本中)提供诊断工具集合。 其次,`JVM设置收藏.txt`可能包含以下内容: 1. **JVM调优**:JVM调优...

    亲测可用java-1.8.0-openjdk.linux.x86_64.zip

    4. **其他开发工具**:OpenJDK 1.8.0还包括其他的开发工具,如`jmap`用于内存映射,`jhat`用于分析堆转储,`jinfo`获取Java配置信息,`jstack`用于查看线程堆栈跟踪,以及`jconsole`图形化监控工具等。这些工具对于...

    JVM---jstack分析Java线程CPU占用,线程死锁的解决

    `jstack` 是JDK自带的一个命令行工具,它能够打印出Java应用程序的线程堆栈信息,包括每个线程的当前状态、调用堆栈、锁定的监视器等。这对于排查线程问题非常有用。 ### 分析CPU占用过高 当Java应用的CPU占用率飙...

    09 Java基础-JVM垃圾回收-玉峰1

    在Java编程语言中,JVM(Java虚拟机)是一个至关重要的组成部分,它负责运行Java程序。JVM垃圾回收是其核心功能之一,旨在自动管理内存,避免程序出现内存泄漏或过度消耗导致的性能问题。本节将深入探讨JVM垃圾回收...

    jstack-review:基于Java的JVM线程转储分析器

    Java线程转储分析器 这是用Java编写的Java线程转储分析器。 它基于的。 有关用法的其他信息,请参见 。 执照 Java Thread Dump Analyzer是根据。 版权所有2014-2016 Spotify AB 版权所有2016-2018 MP Objects BV...

    JVM 参数调优-optimization-jvm.zip

    6. **JVM性能监控和诊断工具**:如JConsole、VisualVM、JProfiler等,它们可以帮助我们实时查看和分析JVM的状态,包括内存、线程、CPU使用率等。 7. **线程堆栈分析**:`-XX:+HeapDumpOnOutOfMemoryError`当出现OOM...

    练习JVM调优-jvm_demo.zip

    在Java开发领域,JVM(Java Virtual Machine)是至关重要的组成部分,它负责解析并执行Java程序。JVM调优是一项核心技能,可以帮助我们优化应用程序的性能,减少内存消耗,提高响应速度,以及避免可能出现的垃圾收集...

    JVM监控工具介绍jstack, jconsole, jinfo, jmap, jdb, jstat.doc

    通过`jconsole`,用户可以监控Java应用的内存使用、Heap大小、线程状态、类加载状态等信息。其图形界面直观易用,适合于快速检查和分析JVM运行状态。 #### 3. jinfo —— Java Configuration Information `jinfo` ...

    【转】Java内存泄露_JVM监控工具介绍jstack_jconsole_jinfo_jmap_jdb_jstat

    通过`jstack &lt;pid&gt;`命令,我们可以获取到Java进程的详细线程信息,包括线程ID、线程状态和调用堆栈,这对于定位线程问题非常有帮助。 其次,`jconsole`是一个图形化的JVM监视工具,它可以提供内存使用情况、线程...

    JVM监控工具介绍jstack_jconsole_jinfo_jmap_jdb_jstat

    该工具利用了内建到JVM中的JMX指令,提供实时的性能和资源的监控,包括Java应用程序的内存使用、Heap size、线程的状态、类的分配状态和空间使用等等。 jinfo jinfo是一个命令行工具,用于从崩溃的Java应用程序的...

    整理-JVM相关面试题2024

    - **线程分析**:通过`jstack`命令获取JVM线程堆栈信息,找出导致CPU使用率升高的线程。 #### 8.1 如果系统响应变慢,你会怎么排查? - **监控**:使用JConsole、VisualVM等工具监控JVM性能指标。 - **日志**:检查...

    05-VIP-JVM调优工具详解(预习资料)1

    Jstack命令可以生成线程dump文件,用于分析Java应用程序的线程信息。例如,使用Jstack命令可以找到占用CPU最高的堆栈信息。 HeapDumpOnOutOfMemoryError是JVM的一个参数,用于在内存溢出时自动导出堆dump文件。例如...

    java-1.8.0-openjdk-1.8.0.282-1.b08.dev.redhat.windows.x86_64.zip

    4. **开发工具**: JDK附带了一系列用于开发和调试Java应用的工具,如javadoc(生成API文档),jconsole(监控Java应用),jmap(内存映射工具),jstack(线程堆栈跟踪)等。 5. **Java语言特性**: Java 8引入了...

    后端JAVA虚拟机JVM调优必备工具

    二、此工具线程的几种状态 1.死锁,Deadlock(重点关注)  2.执行中,Runnable(重点关注)  3.等待资源,Waiting on condition(重点关注)  4.等待监控器检查资源,Waiting on monitor  5.暂停,Suspended  ...

    2024年java面试题-jvm性能调优面试题第二部分

    ### 2024年Java面试题:JVM性能调优面试题第二部分 #### 内存模型及分区 在Java虚拟机(JVM)中,内存主要被划分为以下几个区域: 1. **堆区(Heap)**:堆区是用于存储初始化的对象、成员变量等数据的地方。所有对象...

Global site tag (gtag.js) - Google Analytics