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)