一、线程5大状态
-
新生状态
当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。例如:Thread t1 = new Thread() 。 -
可运行状态(就绪状态):
线程对象创建后,其他线程(比如 main 线程)调用了该对象的 start 方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取 cpu 的使用权。例如:t1.start() 。
以下情况将进入可运行状态:- start方法
- 时间片用完,jvm 把cpu切换给其它线程
- Yield 让出cpu
- 阻塞解除
-
运行状态
线程获得 CPU 资源正在执行任务(#run() 方法),此时除非此线程自动放弃 CPU 资源或者有优先级更高的线程进入,线程将一直运行到结束。 -
阻塞状态:
由于某种原因导致正在运行的线程让出 CPU 并暂停自己的执行,即进入堵塞状态。直到线程进入可运行(runnable)状态,才有机会再次获得 CPU 资源,转到运行(running)状态。
阻塞的情况有4种:- sleep 抱着资源睡觉
- wait 放开资源等待
- join 其它线程插队
- io操作 read write
-
死亡状态
当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。
死亡情况有4种:- 正常结束
- Stop【不推荐】
- Destroy【不推荐】
- 外界干预
二、模拟线程状态
1、模拟sleep阻塞状态
package com.hello.state;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 倒计时,模拟网络阻塞
*/
public class BlockSleep03 {
public static void main(String[] args) throws InterruptedException {
// 倒计时10s,所以加10s
Date endDate = new Date(System.currentTimeMillis()+1000*10);
long end = endDate.getTime();
while (true) {
System.out.println(new SimpleDateFormat("mm:ss").format(endDate));
Thread.sleep(1000);
endDate = new Date(endDate.getTime() - 1000);
if (end - 10000 > endDate.getTime()) {
break;
}
}
}
}
2、模拟死亡状态【外界干预】
package com.hello.state;
/**
* 模拟:终止线程
* 1、正常结束
* 2、外界干预
* 不要使用stop、destroy方法
*/
public class TerminateThread implements Runnable{
// 定义一个标志位
private boolean flag = true;
private String name;
public TerminateThread(String name) {
this.name = name;
}
@Override
public void run() { // 运行状态
int i=0;
while (flag){
System.out.println(name +"--->"+i++);
}
}
public void terminate() {
this.flag = false;
}
public static void main(String[] args) {
TerminateThread tt = new TerminateThread("CC");
new Thread(tt).start();// 新生状态->就绪状态
for (int i=0; i<99; i++) {
if (i==88){
tt.terminate(); // 结束状态
System.out.println("线程终止");
}
System.out.println("main--->"+i);
}
}
}
3、模拟yield线程礼让
package com.hello.yield;
/**
* yield礼让线程,暂停线程直接进入就绪状态
*/
public class YieldDemo02 {
public static void main(String[] args) {
new Thread(()->{
for(int i=0; i<20; i++) {
if (i%5==0) {
Thread.yield(); // 线程礼让
}
System.out.println("lambda-------" + i);
}
}).start();
for(int i=0; i<20; i++) {
System.out.println("main------"+i);
}
}
}
4、模拟join线程插队
package com.hello.join;
/**
* join 插队线程
*/
public class JoinDemo01 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(()->{
for(int i=0; i<100; i++) {
System.out.println("lambda-------" + i);
}
});
t.start();
for(int i=0; i<100; i++) {
if (i==20) {
t.join(); // 插队,main被阻塞
}
System.out.println("main------"+i);
}
}
}
参考资料:
芋道源码
网友评论