写一个示例代码,把几种常见的情况都开一个线程运行
package cn.oopeak.juc.juc1;import cn.hutool.core.thread.ThreadUtil;import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.ReentrantLock;/*** @author fhf* @since 2024/7/5*/
public class VisualVMThreadStatus {public static void main(String[] args) {VisualVMThreadStatus visualVMThreadStatus = new VisualVMThreadStatus();// 创建线程,但是不调用startvisualVMThreadStatus.create();// 调用sleep方法休眠visualVMThreadStatus.sleep();// 调用wait方法visualVMThreadStatus.callWait();// 调用wait(timeout)方法visualVMThreadStatus.callWaitTimeOut();// 同步代码块里面,一个能拿到锁,一个拿不到阻塞visualVMThreadStatus.sync();// juc包中的可重入锁,让线程lock拿不到锁visualVMThreadStatus.juc();// 调用LockSupper.park方法visualVMThreadStatus.lockSupport();for (; ; ) ;}private void create() {new Thread(() -> {for (; ; ) ;}, "1-start");}public void sleep() {new Thread(() -> {try {TimeUnit.DAYS.sleep(1);} catch (InterruptedException e) {throw new RuntimeException(e);}}, "2-sleep").start();}public void callWait() {new Thread(() -> {synchronized (this) {try {wait();} catch (InterruptedException e) {throw new RuntimeException(e);}}}, "3-wait").start();}public void callWaitTimeOut() {new Thread(() -> {synchronized (this) {try {wait(1000000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}, "4-wait-timeout").start();}public void sync() {Object lock = new Object();new Thread(() -> {synchronized (lock) {for (; ; ) ;}}, "5-synchronized持有锁").start();ThreadUtil.sleep(100);new Thread(() -> {synchronized (lock) {System.out.println("t-synchronized等待锁");}}, "6-synchronized等待锁").start();}public void juc() {ReentrantLock r = new ReentrantLock();// 先占用锁r.lock();new Thread(() -> {// 这里就拿不到了r.lock();}, "7-juc-lock").start();}public void lockSupport() {new Thread(() -> {LockSupport.park();}, "8-lockSupport").start();}
}
按照上面的代码运行结果,查看VisualVM里面的线程可以得出以下结论:
- 新建一个线程,但是不调用
start
方法不会显示在列表中; - 正常执行代码的线程,显示的是
Running
(运行)状态; - 调用线程的
sleep
方法,显示的是Sleep
(休眠)状态; - 调用
wait()
方法和调用wait(timeout)
,显示的是Wait
(等待)状态; - 执行
synchronized
代码块(synchronized
方法也一样)如果获取到了锁,显示的是Running
运行状态;如果未获取到锁,显示的是Monitor
(监视)状态。Monitor
状态其实就是阻塞状态; - 调用juc包下的
ReentrantLock
类的lock
方法,未拿到锁的情况下,会显示Park
(驻留)状态; - 调用
LockSupport.park()
方法,会显示Park
(驻留)状态。
我这个VisualVM是官网下载的新版,这个界面和java8自带的差别在于Monitor监视器的颜色,旧版的颜色在一些低质量显示器上还真的和park的颜色分不清
旧的截图:
线程转储中线程的状态