Java线程有6种状态
Java线程在运行的声明周期有6中不同的状态,给任一时刻,线程只能处于其中一种状态:
状态 | 说明 |
---|---|
NEW | 初始状态,线程被构建的,但是还没有调用start()方法 |
RUNNABLE | 运行状态,这里包括操作系统中的就绪和运行两种状态,Java统称“运行中” |
BLOCKED | 阻塞,标识线程阻塞于锁 |
WAITING | 等待,标识当前线程需要等待其他线程作出一些特定操作(通知或中断) |
TIME_WAITING | 超时等待,不同于WAITING,可在指定时间后自行返回 |
TERMINATED | 中止,标识线程已经执行完毕 |
示例代码: ThreadState
代码语言:javascript复制/**
* Java线程的各种状态
*
* @author pengjunzhe
*/
public class ThreadState {
public static void main(String[] args) {
new Thread(new TimeWaiting(), "TimeWaitingThread").start();
new Thread(new Waiting(), "WaitingThread").start();
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 {
@Override
public void run() {
synchronized (Blocked.class) {
while (true) {
SleepUtils.second(100);
}
}
}
}
}
SleepUtils
代码语言:javascript复制import java.util.concurrent.TimeUnit;
public class SleepUtils {
public static final void second(long seconds) {
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
查看线程pid:
代码语言:javascript复制$jps
48316 ThreadState
48317 Jps
查看线程状态:
代码语言:javascript复制$jstack 48316
"TimeWaitingThread" #13 prio=5 os_prio=31 tid=0x00007fe47383b000 nid=0xa703 waiting on condition [0x000070000928f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at com.junzerg.threads.SleepUtils.second(SleepUtils.java:8)
at com.junzerg.threads.ThreadState$TimeWaiting.run(ThreadState.java:24)
at java.lang.Thread.run(Thread.java:748)
"WaitingThread" #14 prio=5 os_prio=31 tid=0x00007fe47481b000 nid=0x5903 in Object.wait() [0x0000700009392000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x000000076ae4b270> (a java.lang.Class for com.junzerg.threads.ThreadState$Waiting)
at java.lang.Object.wait(Object.java:502)
at com.junzerg.threads.ThreadState$Waiting.run(ThreadState.java:38)
- locked <0x000000076ae4b270> (a java.lang.Class for com.junzerg.threads.ThreadState$Waiting)
at java.lang.Thread.run(Thread.java:748)
"BlockedThread-1" #15 prio=5 os_prio=31 tid=0x00007fe470853800 nid=0xa403 waiting on condition [0x0000700009495000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at com.junzerg.threads.SleepUtils.second(SleepUtils.java:8)
at com.junzerg.threads.ThreadState$Blocked.run(ThreadState.java:55)
- locked <0x000000076ae4f498> (a java.lang.Class for com.junzerg.threads.ThreadState$Blocked)
at java.lang.Thread.run(Thread.java:748)
Java线程状态之间的变化
- 线程实例化之后进入初始状态(NEW)
- 调用Thread.start()方法后进入运行状态(RUNNABLE)
- 操作系统调度线程在就绪(READY)和运行中(RUNNING)状态中切换
- JVM能用yield()方法使进程从运行中切换到就绪,其他不能干涉
- 线程可以在RUNNABLE和WAITING间切换:
- 以下方法可以使进程从RUNNABLE切换到WAITING:
- Object.wait()
- Object.join()
- LockSupper.park()
- 以下方法使进程从WAITING切换到RUNNABLE:
- Object.notify()
- Object.notifyAll()
- LockSupper.unpark(Thread)
- 以下方法可以使进程从RUNNABLE切换到WAITING:
- 线程可以在RUNNABLE和TIMED_WAITING间切换:
- 以下方法使进程从RUNNABLE切换到TIMED_WAITING:
- Thread.sleep(long)
- Object.wait(long)
- Object.join(long)
- LockSupper.parkNanos()
- LockSupper.parkUntil()
- 以下方法使线程从TIME_WAITING切换到到RUNNABLE:
- Object.notify()
- Object.notifyAll()
- LockSupper.unpark(Thread)
- 超时时间到
- 以下方法使进程从RUNNABLE切换到TIMED_WAITING:
- 线程可以在RUNNABLE和BLOCKED中切换
- 以下方法线程从RUNNABLE切换到BLOCKED:
- 等待进入synchronize方法
- 等待进入synchronize块
- 以下方法线程从阻塞切换到RUNNABLE:
- 获取到锁
- 以下方法线程从RUNNABLE切换到BLOCKED:
- 线程执行完成后进入中止状态(TERMINATED)