1.认识线程的状态
NEW
:Thread对象已经创建好了,但还没有调用start方法在系统中创建线程
RUNNABLE
:就绪状态,表示这个线程正在CPU上执行,或准备就绪,随时可以去CPU上执行
BLOCKED
:表示由于锁竞争,引起的阻塞
WAITING
:表示不带时间的阻塞,死等(join()
,wait()
)
TIMED_WAITING
:表示指定时间的阻塞,到达一定时间自动解除阻塞(sleep或带超时时间的join)
TERMINATED
:表示Thread对象仍存在,但是系统内部的线程已经执行完了
2.线程状态和状态转移的意义
学习这些状态的最大作用就是调试多线程代码bug时,给我们作为重要的参考依据,程序卡住了就意味着一些关键的线程阻塞了,就可观察线程的状态,分析出一些原因,若发现进程卡住,可用jconsole这样的工具查看进程中的一些重要线程状态和调用栈,可判定是否阻塞或什么原因引起的阻塞
3.案例
关注
NEW
、RUNNABLE
、TERMIANTED
状态的切换
public class demo {
public static void main(String[] args) {
Thread t = new Thread(()->{
for (int i = 0; i < 1; i++) {
}
},"t1");
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());
}
}
//输出结果
t1 : NEW
t1 : RUNNABLE
t1 : TERMINATED
Process finished with exit code 0
关注
WAITING
、BLOCKED
、TIMED_WAITING
状态的切换
public class demo2 {
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) {
throw new RuntimeException(e);
}
}
}
}
},"t1");
t1.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (object){
System.out.println("hehe");
}
}
},"t2");
t2.start();
}
}
我们用jconsole来观察线程状态
修改上面的代码,把t1中的sleep换成wait
public class demo3 {
public static void main(String[] args) {
final Object object = new Object();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (object){
try {
object.wait();
} 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();
}
}