java · 2025-09-30 0

探究 JAVA 线程 BLOCKED 状态

1.探究线程 BLOCKED 状态

1) java 代码

// 共享对象,用于同步
private static final Object LOCK = new Object();

@Test
public void testBlocked() throws Exception {
    MyRunnable runnable = new MyRunnable();

    // 创建两个线程,竞争同一个锁
    Thread thread0 = new Thread(runnable, "Thread-0");
    Thread thread1 = new Thread(runnable, "Thread-1");

    // thread1 的状态:NEW      thread2 的状态:NEW
    System.out.println("Thread-0 状态: " + thread0.getState());
    System.out.println("Thread-1 状态: " + thread1.getState());

    // 启动线程
    thread0.start();
    thread1.start();

    // 观察线程状态
    Thread.sleep(50);

    // thread1 的状态:TIMED_WAITING      thread2 的状态:BLOCKED (等待锁)
    System.out.println("Thread-0 状态: " + thread0.getState());
    System.out.println("Thread-1 状态: " + thread1.getState());

    // 等待线程执行完毕
    thread0.join();
    thread1.join();

    // thread1 的状态:TERMINATED      thread2 的状态:TERMINATED
    System.out.println("Thread-0 状态: " + thread0.getState());
    System.out.println("Thread-1 状态: " + thread1.getState());

    System.out.println("所有线程执行完毕。");
}

private class MyRunnable implements Runnable {

    @Override
    public void run() {
        synchronized (LOCK) {
            String threadName = Thread.currentThread().getName();
            System.out.println(threadName + " 获得了锁,进入临界区。");
            try {
                // 模拟耗时操作,20秒
                Thread.sleep(20000);
            } catch (InterruptedException e) {
                System.err.println(e.getMessage());
            }
            System.out.println(threadName + " 释放了锁。");
        }
    }
}

2) 结果

Thread-0 状态: NEW
Thread-1 状态: NEW
Thread-0 获得了锁,进入临界区。
Thread-0 状态: TIMED_WAITING
Thread-1 状态: BLOCKED
Thread-0 释放了锁。
Thread-1 获得了锁,进入临界区。
Thread-1 释放了锁。
Thread-0 状态: TERMINATED
Thread-1 状态: TERMINATED
所有线程执行完毕。

3) arthas 查看线程

[arthas@9943]$ thread
Threads Total: 39, NEW: 0, RUNNABLE: 10, BLOCKED: 1, WAITING: 4, TIMED_WAITING: 7, TERMINATED: 0, Internal threads: 17                                                                                             
ID       NAME                                                 GROUP                     PRIORITY          STATE            %CPU              DELTA_TIME       TIME              INTERRUPTED      DAEMON 
1        main                                                 main                      5                 WAITING          0.0               0.000            0:0.167           false            false             
13       Thread-0                                             main                      5                 TIMED_WAITING    0.0               0.000            0:0.000           false            false             
14       Thread-1                                             main                      5                 BLOCKED          0.01              0.000            0:0.000           false            false             

[arthas@15413]$ thread 14
"Thread-1" Id=14 BLOCKED on java.lang.Object@3ade148b owned by "Thread-0" Id=13
    at org.example.MyTest$MyRunnable.run(MyTest.java:49)
    -  blocked on java.lang.Object@3ade148b
    at java.lang.Thread.run(Thread.java:750)

[arthas@15413]$ thread 13
"Thread-0" Id=13 TIMED_WAITING
    at java.lang.Thread.sleep(Native Method)
    at org.example.MyTest$MyRunnable.run(MyTest.java:53)
    at java.lang.Thread.run(Thread.java:750)

[arthas@15413]$ thread -b
"Thread-0" Id=13 TIMED_WAITING
    at java.lang.Thread.sleep(Native Method)
    at org.example.MyTest$MyRunnable.run(MyTest.java:53)
    -  locked java.lang.Object@3ade148b <---- but blocks 1 other threads!
    at java.lang.Thread.run(Thread.java:750)

2.探究线程 DeadLock

1) java 代码

private static final Object A = new Object();

private static final Object B = new Object();

@Test
public void testDeadLock() throws Exception {
    Thread thread0 = new Thread(new MyRunner0(), "Thread-0");
    Thread thread1 = new Thread(new MyRunner1(), "Thread-1");

    // 启动线程
    thread0.start();
    thread1.start();

    thread0.join();
    thread1.join();
}

private class MyRunner0 implements Runnable  {

    @Override
    public void run() {
        synchronized (A) {
            System.out.println("Thread-0 got A, trying to get B...");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                System.err.println(e.getMessage());
            }
            synchronized (B) {
                System.out.println("Thread-0 got B");
            }
        }
    }
}

private class MyRunner1 implements Runnable {

    @Override
    public void run() {
        synchronized (B) {
            System.out.println("Thread-1 got B, trying to get A...");
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                System.err.println(e.getMessage());
            }
            synchronized (A) {
                System.out.println("Thread-1 got A");
            }
        }
    }
}

2) 结果

Thread-0 got A, trying to get B...
Thread-1 got B, trying to get A...

3) arthas 查看线程

[arthas@9943]$ thread
Threads Total: 39, NEW: 0, RUNNABLE: 10, BLOCKED: 1, WAITING: 4, TIMED_WAITING: 7, TERMINATED: 0, Internal threads: 17                                                                                             
ID       NAME                                                 GROUP                     PRIORITY          STATE            %CPU              DELTA_TIME       TIME              INTERRUPTED      DAEMON 
1        main                                                 main                      5                 WAITING          0.0               0.000            0:0.166           false            false             
13       Thread-0                                             main                      5                 BLOCKED          0.0               0.000            0:0.000           false            false             
14       Thread-1                                             main                      5                 BLOCKED          0.0               0.000            0:0.000           false            false             

[arthas@15756]$ thread 13
"Thread-0" Id=13 BLOCKED on java.lang.Object@2a4c5220 owned by "Thread-1" Id=14
    at org.example.MyTest$MyRunner0.run(MyTest.java:91)
    -  blocked on java.lang.Object@2a4c5220
    at java.lang.Thread.run(Thread.java:750)

[arthas@15756]$ thread 14
"Thread-1" Id=14 BLOCKED on java.lang.Object@43e001e1 owned by "Thread-0" Id=13
    at org.example.MyTest$MyRunner1.run(MyTest.java:109)
    -  blocked on java.lang.Object@43e001e1
    at java.lang.Thread.run(Thread.java:750)

[arthas@15756]$ thread -b
"Thread-0" Id=13 BLOCKED on java.lang.Object@2a4c5220 owned by "Thread-1" Id=14
    at org.example.MyTest$MyRunner0.run(MyTest.java:91)
    -  blocked on java.lang.Object@2a4c5220
    -  locked java.lang.Object@43e001e1 <---- but blocks 1 other threads!
    at java.lang.Thread.run(Thread.java:750)