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 : TERMINATEDProcess 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() {@Overridepublic 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() {@Overridepublic 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() {@Overridepublic void run() {synchronized (object){try {object.wait();} catch (InterruptedException e) {e.printStackTrace();}}}},"t1");t1.start();Thread t2 = new Thread(new Runnable() {@Overridepublic void run() {synchronized (object){System.out.println("hehe");}}},"t2");t2.start();}
}