1 首先我们先通过书上例子来说明线程状态。
下面例子
- TimeWaiting只是设置了循环休眠,
- Waiting循环休眠,并且获取了锁,并调用wait()方法等待某个唤醒的时机
- Blocked循环并获取锁,重点是还有多个线程去争这个锁(BlockedThread-1、BlockedThread-2)
public class ThreadState {
public static void main(String[] args) {
new Thread(new TimeWaiting(), "TimeWaitingThread").start();
new Thread(new Waiting(), "WaitingThread").start();
// 使用两个Blocked线程,一个获取锁成功,另一个被阻塞
new Thread(new Blocked(), "BlockedThread-1").start();
new Thread(new Blocked(), "BlockedThread-2").start();
}
// 该线程不断地进行睡眠
static class TimeWaiting implements Runnable {
@Override
public void run() {
while (true) {
SleepUtils.second(100);
}
}
}
// 该线程在Waiting.class实例上等待
static class Waiting implements Runnable {
@Override
public void run() {
while (true) {
synchronized (Waiting.class) {
try {
Waiting.class.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
// 该线程在Blocked.class实例上加锁后,不会释放该锁
static class Blocked implements Runnable {
public void run() {
synchronized (Blocked.class) {
while (true) {
SleepUtils.second(100);
}
}
}
}
}
class SleepUtils {
public static void second(long seconds) {
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (InterruptedException ignored) {
}
}
}
然后我们可以敲以下命令分析下线程的状态:
# jps
152752 ThreadState
201992
203944 Launcher
207064 Jps
# jstack 152752 // 结果如下
由上可见:TimeWaitingThread处于time_waiting状态。WaitingThread处于waiting状态,等待被唤醒。BlockedThread-1拿到了锁不释放,导致BlockedThread-2一直在等他释放(被阻塞了)。
2 线程状态的变化
总的来说,线程不是一成不变的,大致有如下几种状态:new、running、ready、waiting、blocked、timed_waiting、terminated
-- 注:waiting与timed_waiting区别(timed_waiting具有超时等待机制,超过时间就会返回运行状态)