本文介绍jvm中的线程状态,及线程的状态转换。
1.JVM中的线程状态
JVM线程的生命周期有6中状态,分别如下:
1.1 NEW(新生态)
新生的线程,没有调用start()启动的状态。
1.2 RUNABLE(可运行)
仅仅是在java虚拟机中运行,但是可能在等在操作系统的资源,比如处理器。
1.3 BLOCK(阻塞)
等待监视器锁的状态。
1.4 WATTING(等待)
等待其他线程执行某些操作。
1.5 TIMED_WATTING(限时等待)
等待其他线程执行某些操作,或者等待指定时限。
1.6 TERMINATED(终止)
线程执行完毕。
注意:在JVM中,线程只有这6种状态。
下面详细解释下这6种状态比较容易让人混淆的状态然后给出一个线程状态转化的状态图。NEW没有什么好解释的,就是新建Thread类的实例;RUNNABLE,java api给出了很好的解释,不再进行画蛇添足的解释了就;TERMINATED也没有什么好解释的。
WATTING和TIMED_WATTING基本是一样的,都是表示当前线程在等待其他线程执行某些操作。区别就是WATTING状态的线程如果不被其他线程唤醒将一直等待,而TIMED_WATTING状态的线程除了可以被其他线程唤醒来结束等待状态,还可以在指定的等待时间结束后唤醒。
在我们刚开始接触多线程编程时,最容易混淆的就是BLOCK和WATTING/TIMED_WATTING的概念了。
还是从API的解释入手,关于BLOCK是这么定义的,处于这种状态的表示正在等待监视器锁。相信大家都跟我有一样的疑问,什么是监视器锁?关于这个问题在翻了API跟线程相关的知识点,
甚至JVM规范对于同步的支持后,都没有找到相关的文档。在搜索了相关信息后,终于在IMB developerWorks上面找到的答案,监视器锁是并发设计模式-Monitor Object模式-结构的一部分,
详情请参考:http://www.ibm.com/developerworks/cn/java/j-lo-synchronized/
简单来说在这个模式下,想要在并发开发中保证代码的原子性,需要先获得监视器锁。我们现在只需要知道,对于开发而言java语言对获取锁的操作做了透明的处理,当我们使用synchronized关键字时,
就会竞争监视器锁,这是一种隐式获取锁的方法,这大大简化了并发编程开发的难度,但是也使得获取释放锁的操作变得不那么灵活。
这样,在java语言中想要获取监视器锁,假如不适用并发包中的Lock和Condition,只能通通过synchronized关键字获取监视器锁。
也就是说,处于WATTING状态的线程是在等待其他线程唤醒,唤醒后的线程并不会立即进入RUNNABLE状态,它需要与其他线程竞争监视器锁,最终竞争到监视器锁的线程才能真正去执行,
而等待获取(竞争)监视器锁的状态就是BLOCK状态了。
下面给出线程的状态图:
下面通过一段代码简单说明下线程之间的转换:
private static Object alock = new Object();
private static Object block = new Object();
private static boolean flag = true;
public static void main(String[] args) throws InterruptedException {
Thread athread = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
synchronized (alock) {
// System.out.println("线程athread获取锁alock。");
synchronized (block) {
// System.out.println("线程athread获取锁block。");
try {
alock.wait();
// System.out.println("线程athread被唤醒后恢复执行。");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
Thread bthread = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
//空执行,为了在main线程中看到bthread的RUNNABLE状态
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (block) {
// System.out.println("线程bthread获取锁block。");
}
while(flag){
}
// System.out.println("线程bthread执行完毕。");
}
});
System.out.println("线程bthread的新生状态:" + bthread.getState());
athread.start();
bthread.start();
System.out.println("线程bthread的可运行状态:" + bthread.getState());
Thread.sleep(50);
System.out.println("线程bthread等待状态:" + bthread.getState());
Thread.sleep(120);
System.out.println("线程bthread阻塞状态:" + bthread.getState());
synchronized (alock) {
alock.notifyAll();
}
Thread.sleep(10);
System.out.println("线程bthread恢复为可运行状态:" + bthread.getState());
flag = false;
Thread.sleep(10);
System.out.println("线程bthread终止状态:" + bthread.getState());
}
结果如下:
线程bthread的新生状态:NEW
线程bthread的可运行状态:RUNNABLE
线程bthread等待状态:TIMED_WAITING
线程bthread阻塞状态:BLOCKED
线程bthread恢复为可运行状态:RUNNABLE
线程bthread终止状态:TERMINATED
时序图如下: