线程的状态
获取线程状态
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-TERMINATED状态
使用isAlive()判断存活状态,除了NEW和TERMINATED状态都是存活状态。
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());
}
可以看到当线程刚刚被实例化的时候(也就是被new出来的时候),这个时候的状态就是NEW了。准备运行和正在运行都是RUNNABLE,运行结束是TERMINATE。
观察三个排队等待BLOCKED - WAITING - TIMED_WAITING
public static void main(String[] args) {
final Object object = new Object();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (object) {
int i=10;
while (i-->0) {
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();
}
这里的synchronized关键字是作为同步锁使用的,作用是将线程按顺序同步起来,使之处于同一个时间排序的运行状态(个人是这样理解的)。
可能这样解释不好理解,我还是附上一些优秀的总结吧。
链接: synchronized的优秀解答之一
链接: jconsole的使用一
链接: jconsole的使用二
舍己为人yield()
当一个线程使用yield()方法的时候,如果出现和其他线程冲突的情况会放弃自身的cpu使用,到后面去排队。
public static void main(String[] args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.out.println("kunkun");
// 先注释掉, 再放开
// Thread.yield();
}
}
}, "t1");
t1.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
while (true) {
System.out.println("tiantianquan");
}
}
}, "t2");
t2.start();
}
使用yield之前kunkun和tiantianquan是一半一半的执行运行,在使用yield之后kunkun的运行明显比tiantianquan少了很多。