线程状态
线程状态在windows,linux和android等OS中状态都是不一致的,Java对线程状态做了一个抽象。
在java中线程状态由Thread内部内State表示
java.lang.Thread.State
These states are virtual machine states which do not reflect any operating system thread states.
这些线程状态不等于任何操作系统的线程状态
线程状态有,NEW,RUNABLE,WATING,TIMED_WAITING,TERMINATED
NEW
A thread that has not yet started is in this state.
一个线程被new出来后,并没有开始执行。
RUNNABLE
A thread executing in the Java virtual machine is in this state.
一个线程在JVM进程中运行的状态。
BLOCKED
A thread that is blocked waiting for a monitor lock is in this state.
一个线程在等待monitor lock 进入的状态。
WAITING
A thread that is waiting indefinitely for another thread to perform a particular action is in this state.
无限等待其他线程执行的状态。
TIMED_WAITING
A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.
有限时间内等待其他线程执行的状态
TERMINATED
A thread that has exited is in this state.
线程已经退出的状态。
Java线程状态实例
RUNNABLE
public static void runnable() {
Thread thread = new Thread(() -> {
while (true) {
}
}, "Runnable 状态的线程");
thread.start();
}
控制台监控的状态,简史和管理控制台通过(jconsole 监控工具查看,和之前提到的jvisualvm类似,jvisualvm后出来,也可以用jstack <pid>查看,jstack是命令行工具,三个监控工具,结果是一致的。)
BLOCKED
阻塞状态实例,等待synchronized(class字节码层面的monitorenter)进入的状态。
public static void blocked() throws InterruptedException {
final Object object = new Object();
Thread runnableThread = new Thread(() -> {
synchronized (object) {
while (true) {
}
}
}, "Runnable 状态的线程");
Thread blockedThread = new Thread(() -> {
synchronized (object) {
}
}, "blocked 状态的线程。");
runnableThread.start();
//等待runnable 线程已经启动后再启动blockedThread
Thread.sleep(500);
blockedThread.start();
}
控制台结果
WAITING
waiting状态,在三种情况下可以出现,Object.wait,Thread.join,LockSupport.park
object.wait实例
这里在object上调用wait()方法的前提是必须要synchronized()获取锁后,不然会抛错,与之相对的释放状态就是object.notify()(随机唤醒在object上监听的一个线程,让它获取object的锁)或object.notifyAll()(通知所有监听在object对象上的线程,让他们同时竞争,只有一个可以获取object上的锁),由于没法唤醒指定的线程获取object的锁,所以,在java1.5就出现了Lock和Condition,后面会详细讲Lock。
private static void waiting() throws InterruptedException {
final Object object = new Object();
Thread waitingThread = new Thread(() -> {
synchronized (object) {
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "waiting 状态的线程");
waitingThread.start();
}
监控情况
thread.join实例
private static void join() throws InterruptedException {
Thread joinThread = new Thread(() -> {
Thread runnableThread = new Thread(() -> {
while (true) {
}
}, "runnable 线程.");
runnableThread.start();
try {
runnableThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "等待join的线程 状态的线程");
joinThread.start();
}
监控实例
runnable线程状态
join线程状态
LockSupport.park实例
private static void lockSupport() {
new Thread(() -> {
LockSupport.park();
}, "lockSupport 线程。").start();
}
监控状态
TIMED_WAITING
timed_waiting状态有调用5个方法中的一种,就会出现,Thread.sleep,Object#wait(long) ,join(long) ,LockSupport#parkNanos ,LockSupport#parkUntil
thread.sleep
用的就比较多,我就不多说了,示例代码。提一点,TimeUnit.SECONDS.sleep(1000*60);这样写也是可以的
private static void sleep() {
new Thread(() -> {
try {
Thread.sleep(60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "sleep 线程。").start();
}
控制台
Object.wait(long)
对象毫秒等待
private static void objectWait() {
Object object = new Object();
new Thread(() -> {
synchronized (object) {
try {
object.wait(1000 * 60);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, "object.wait 线程。").start();
}
监控
Thread.join(long)
毫秒等待线程线程结束
private static void timedJoin() throws InterruptedException {
Thread joinThread = new Thread(() -> {
Thread runnableThread = new Thread(() -> {
while (true) {
}
}, "runnable 线程.");
runnableThread.start();
try {
runnableThread.join(1000 * 60);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "等待join的线程状态的线程");
joinThread.start();
}
监控状态
runnable线程状态
join线程状态
LockSupport.parkNanos(long)
纳秒时间等待,1000000000纳秒=1秒在java中数值类型可以加下划线在java1.5中的特性比如: int i = 1_00;double d = 1.00_01d;这样写是合法的,便于阅读。
private static void lockSupoortNanosObject() throws InterruptedException {
final Object object = new Object();
Thread lockSupportObjectThread = new Thread(() -> {
//停顿60s
LockSupport.parkNanos(object, 1000_000_000L * 60);
}, "lockSupportObjectThread 线程");
lockSupportObjectThread.start();
}
监控状态
LockSupport.parkUntil
等待绝对时间,直到什么时刻为止,实例代码等待距现在60s
private static void lockSupportParkUntil() {
Thread thread = new Thread(()->{
LockSupport.parkUntil(System.currentTimeMillis()+1000*60);
},"lockSupportParkUtil 线程");
thread.start();
}
监控
总结
这一讲主要对java的5中线程状态做了实例说明,这里需要注意一点小细节,在创建线程的时候,务必带上名称,方便监控,下一讲,我们进入线程的使用,包括线程的状态转移。