当你的多线程代码结构很复杂的时候很难找出bug的原因所在,此时我们可以使用getState()方法获取该线程当前的状态,通过观察其状态是阻塞了还是因为没有启动等原因导致的。
状态 | 描述 |
---|---|
NEW | 安排了工作,还未开始行动 |
RUNNABLE | 可工作的,又可以分成正在工作中和即将开始工作 |
BLOCKED | 这几个都表示排队等着其他事情 |
WAITING | 这几个都表示排队等着其他事情 |
TIMED_WAITING | 这几个都表示排队等着其他事情 |
TERMINATED | 工作完成了 |
NEW
此状态说明这个线程已经被创建了,但是没有start()执行任务。
java
Thread t = new Thread(() -> {
for (int i = 0; i < 1000_0000; i++) {
}
}, "状态");
System.out.println(t.getName() + ": " + t.getState());
RUNNABLE
这个状态表明他已经被创建,但是还没有执行完任务,在这个过程中都是RUNNABLE状态。
java
Thread t = new Thread(() -> {
for (int i = 0; i < 1000_0000; i++) {
}
}, "状态");
t.start();
while (t.isAlive()) {
System.out.println(t.getName() + ": " + t.getState());
}
TERMINATED
已经执行完任务了,是线程结束的标志
java
Thread t = new Thread(() -> {
for (int i = 0; i < 1000_0000; i++) {
}
}, "状态");
t.start();
t.join();
System.out.println(t.getName() + ": " + t.getState());
WAITING
当他在使用wait,join,sleep方法等待的时候,并且方法没有传入参数,也就是死等的时候,需外部唤醒(如 notify()),处于此状态。
java
Thread t1 = Thread.currentThread();
Thread t = new Thread(() -> {
try {
t1.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}, "状态");
t.start();
Thread.sleep(10);
System.out.println(t.getState());
TIMED_WAITING
当他在使用wait,join,sleep方法等待的时候,并且传入参数会进入此状态,超时后自动唤醒或外部提前唤醒,和WAITING的区别就是是否传入参数的区别。
java
Thread t1 = Thread.currentThread();
Thread t = new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}, "状态");
t.start();
Thread.sleep(10);
System.out.println(t.getState());
BLOCKED
因为锁竞争导致的等待时,会进入此状态,如果一直是此状态可能是陷入了死锁。
java
//这个案例是个死锁。
Object locker1 = new Object();
Object locker2 = new Object();
Thread t1 = new Thread(()->{
synchronized (locker1) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (locker2) {
}
}
System.out.println("t1执行完毕");
});
Thread t2 = new Thread(()->{
synchronized (locker2) {
synchronized (locker1) {
}
}
System.out.println("t2执行完毕");
});
t1.start();
t2.start();
Thread.sleep(100);
System.out.println(t1.getState());