目录
一、线程的状态
1.1 观察线程的所有状态
1.2 线程状态和状态转移的意义
1.2.1 NEW、RUNNABLE、TERMINATED状态转换
1.2.2 WAITING、BLOCKED、TIMED_WAITING状态转换
1.2.3 yield()大公无私让出cpu
一、线程的状态
1.1 观察线程的所有状态
public class Demo9 {
public static void main(String[] args) {
for (Thread.State state : Thread.State.values()) {
System.out.println(state);
}
}
}
- NEW: 安排了工作,还未开始行动
- RUNNABLE: 可工作的, 又可以分成正在工作中和即将开始工作.
- BLOCKED: 这几个都表示排队等着其他事情,使用锁
- WAITING: 这几个都表示排队等着其他事情,使用wait
- TIMED_WAITING: 这几个都表示排队等着其他事情,使用sleep
- TERMINATED: 工作完成了
1.2 线程状态和状态转移的意义
1.2.1 NEW、RUNNABLE、TERMINATED状态转换
public class Demo10 {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(()->{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
//线程还没有开始NEW状态
System.out.println(t.getState());
t.start();
//线程正在执行RUNNABLE状态
System.out.println(t.getState());
t.join();
//线程结束 TERMINATED状态
System.out.println(t.getState());
}
}
1.2.2 WAITING、BLOCKED、TIMED_WAITING状态转换
public class Demo11 {
public static void main(String[] args) throws InterruptedException {
Object obj = new Object();
Thread t1 = new Thread(()->{
synchronized (obj) {
try {
//Thread.sleep(10000);//这里显示的就是 TIMED_WAITING
obj.wait();//这里显示的就是 WAITING
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
Thread.sleep(1000);
System.out.println(t1.getState());
}
}
public class Demo12 {
public static void main(String[] args) {
final Object object = new Object();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (object) {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}, "t1");
t1.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (object) {
System.out.println("hehe");
}
}
}, "t2");
t2.start();
System.out.println(t2.getState());
}
}
使用 jconsole 可以看到 t1 的状态是 TIMED_WAITING , t2 的状态是 BLOCKED
结论:
- BLOCKED 表示等待获取锁, WAITING 和 TIMED_WAITING 表示等待其他线程发来通知.
- TIMED_WAITING 线程在等待唤醒,但设置了时限; WAITING 线程在无限等待唤醒
1.2.3 yield()大公无私让出cpu
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.out.println("张三");
// 先注释掉, 再放开
// Thread.yield();
}
}
}, "t1");
t1.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.out.println("李四");
}
}
}, "t2");
t2.start();
可以看到:
1. 不使用 yield 的时候, 张三李四大概五五开
2. 使用 yield 时, 张三的数量远远少于李四
结论:yield 不改变线程的状态, 但是会重新去排队