文章目录
- 一、线程状态
- 二、代码演示
- 1. Threadstate 类
- 2. SleepUtils 类
- 3. 运行示例
- 三、参考资料
一、线程状态
Java线程在运行的生命周期中可能处于下图所示的6种不同的状态,在给定的一个时刻线程只能处于其中的一个状态。
状态名称 | 说明 |
---|---|
NEW | 初始状态,线程被构建,但是还没有调用start()方法 |
RUNNABLE | 运行状态,Java线程将操作系统中的就绪和运行两种状态笼统地称作运行中 |
BLOCKED | 阻塞状态,表示线程阻塞于锁 |
WAITING | 等待状态,表示线程进入等待状态,进入该状态表示当前线程需要等待其他线程做出一些特定动作(通知或中断) |
TIME WAITING | 超时等待状态,该状态不同于 WAITING,它是可以在指定的时间自行返回的 |
TERMINATED | 终止状态,表示当前线程已经执行完毕 |
二、代码演示
1. Threadstate 类
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 interruptedException) {
interruptedException.printStackTrace();
}
}
}
}
}
//该线程在Blocked.class实例上加锁后,不会释放该锁
static class Blocked implements Runnable{
@Override
public void run() {
synchronized (Blocked.class){
while (true){
SleepUtils.second(100);
}
}
}
}
}
2. SleepUtils 类
public class SleepUtils {
public static final void second(long seconds){
try{
TimeUnit.SECONDS.sleep(seconds);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
}
}
3. 运行示例
运行该示例,打开终端或者命爷提示符,键入 jps 输出如下:
可以看到运行示例对应的进程ID是13948,接着再键入jstack 13948,如下:
通过示例,我们了解到Java程序运行中线程状态的具体含义。
线程在自身的生命周期中并不是固定地处于某个状态,而是随着代码的执行在不同的状态之间进行切换,Java线程状态变迁如下图所示:
由上图可以看到,线程创建之后,调用start()方法开始运行。当线程执行wait()方法之后线程进入等待状态。进入等待状态的线程需要依靠其他线程的通知才能够返回到运行状态,而超时等待状态相当于在等待状态的基础上增加了超时限制,也就是超时时间到达时将会返回到运行状态。当线程调用同步方法时,在没有获取到锁的情况下,线程将会进入到阻塞状态。线程在执行Runnable的run()方法之后将会进入到终止状态。
注意事项:
-
Java将操作系统中的运行和就绪两个状态合并称为运行状态。
-
阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态,但是阻塞在java.concurrent包中Lock接口的线程状态却是等待状态,因为iava.concurrent包中Lock接口对于阻塞的实现均使用了LockSupport类中的相关方法。
三、参考资料
Java并发编程的艺术