在这里插入代码片
昨天提出的五虎将–“线程状态”我们应该反复尝试练习并且理解,要知道五虎将在三国历史上可谓是留下了浓墨重彩的一笔,能用它来做比喻那可绝对不是什么心血来潮,不过,对人们来说,比之五虎将本身更重要的是,你得认识谁是谁,不能张冠李戴,所以,今天的重点便是观察“线程状态”。
线程的状态是一个枚举类型 Thread.State,通过一段代码可以实现:
在这里插入代码片
public class ThreadState {
public static void main(String[] args) {
for (Thread.State state : Thread.State.values()) {
System.out.println(state);
}
}
}
NEW
RUNNABLE
BLOCKED
WAITING
TIMED_WAITING
TERMINATED
在这里插入代码片
实际上这里面除了线程状态还涉及到了状态转移,这段代码看似简单却内涵十足,我所拥有的一部教材上关于这个“内涵”有一幅图专门描绘,因为用文字表达实在是没那口才:
看起来或许繁复,枯燥,而且吓人,但能被设计出来的步骤环节那肯定是有它的意义的。
按照我一个新手的初步理解,它大概是这么个意思:
把李四、王五找来,还是给他们在安排任务,没让他们行动起来,就是 NEW 状态(启动);
当李四、王五开始去窗口排队,等待服务,就进入到 RUNNABLE 状态(等待)。该状态并不表示已经被银行工作人员开始接待,排在队伍中也是属于该状态,即可被服务的状态,是否开始服务,则看调度器的调度;
当李四、王五因为一些事情需要去忙,例如需要填写信息、回家取证件、发呆一会等等时,进入 BLOCKED 、WATING 、 TIMED_WAITING 状态(中断,休眠),
如果李四、王五已经忙完,为 TERMINATED 状态(获取完毕)。
刚才是将五个状态输入,现在是真正的观察阶段:
代码
在这里插入代码片
观察 1: 关注 NEW 、 RUNNABLE 、 TERMINATED 状态的转换
public class ThreadStateTransfer {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(() -> {
for (int i = 0; i < 1000_0000; i++) {
}
}, "李四");
System.out.println(t.getName() + ": " + t.getState());;
t.start();
while (t.isAlive()) {
System.out.println(t.getName() + ": " + t.getState());;
}
System.out.println(t.getName() + ": " + t.getState());;
}
}
观察 2: 关注 WAITING 、 BLOCKED 、 TIMED_WAITING 状态的转换
public class ThreadStateTransfer {
public static void main(String[] args) throws InterruptedException {
Object object = new Object();
Thread t = new Thread(() -> {
synchronized (object) {
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 1000_0000; i++) {}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
System.out.println(t.getState());;
t.start();
System.out.println(t.getState());
Thread.sleep(10);
synchronized (object) {
for (int i = 0; i < 10; i++) {
System.out.println(t.getState());
}
object.notify();
}
while (t.isAlive()) {
System.out.println(t.getState());
}
}
}
观察-3: yield() 大公无私,让出 CPU
public class ThreadDemo {
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> {
while (true) {
System.out.println(Thread.currentThread().getName()
+ ": 我跑着呢");
// Thread.yield();
}
}, "李四");
Thread thread2 = new Thread(() -> {
while (true) {
System.out.println(Thread.currentThread().getName()
+ ": 我跑着呢");
}
}, "王五");
thread1.start();
thread2.start();
}
}
//此处注意
//1. yield() 只是让出 CPU,并不会改变自己的状态。也就上面途中,我从柜台前站起,又重新去排队去了
//2. 因为李四总是无私的让出座位,王五并不让座位,所以会导致王五的打印更多。
在这里插入代码片
当然,上述代码还是不是本人所写,说实在的,我也想早点写出自己的代码,但菜鸟毕竟是菜鸟,一口也吃不了那许多。
共勉吧。