欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java-jvm-jstack-线程状态

程序员文章站 2022-05-18 13:06:15
...

常见的线程状态:

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;
    }