当前位置: 首页 > 科技观察

面试惊喜:说说线程的生命周期和转换过程?

时间:2023-03-23 01:23:37 科技观察

作者|雷哥来源|Java面试题解析(ID:aimianshi666)转载请联系授权(微信ID:GG_Stone)线程的生命周期是指一个线程从创建到销毁的整个过程,通常一个线程的生命周期有五个周期:初始状态、可运行状态、休眠状态、终止状态,以及它们的状态转换如下图所示:Java线程生命周期Java线程的生命周期不同于上面提到的生命周期,它有以下六种类型Status:NEW(初始化状态)RUNNABLE(可运行/运行状态)BLOCKED(阻塞状态)WAITING(无限等待状态)TIMED_WAITING(定时等待状态)TERMINATED(终止状态)我们可以在Thread状态的源码中找到这6个,如下如下图:当然也可以使用Java代码打印所有线程状态,如下代码所示:for(Thread.Statevalue:Thread.State.values()){System.out.println(value);}的执行结果上面的程序如下图所示:生命周期转换下面说说Java线程生命周期的转换过程。1、当我们创建一个线程从NEW到RUNNABLE,也就是newThread时,此时线程处于NEW状态,如下代码所示://创建线程Threadthread=newThread(newRunnable(){@Overridepublicvoidrun(){//...}});//获取线程状态Thread.Statestate=thread.getState();System.out.println(state);上面程序的执行结果如下图所示:然而在调用线程的start方法后,线程的状态由NEW变为RUNNABLE,如下代码所示://创建一个线程Threadthread=newThread(newRunnable(){@Overridepublicvoidrun(){//获取当前正在执行的线程ThreadcurrThread=Thread.currentThread();//获取线程状态Thread.Statestate=currThread.getState();//打印线程状态System.out.println(state);}});thread.开始();上述程序的执行结果如下图所示:2.从RUNNABLE到BLOCKED当线程中的代码排队执行synchronized时,线程会从RUNNABLE状态变为BLOCKED阻塞状态,如下图以下代码://创建线程Threadthread=newThread(newRunnable(){@Overridepublicvoidrun(){try{//等待100毫秒Thread.sleep(100);}catch(InterruptedExceptione){e.打印堆栈跟踪();}System.out.println("队列锁");synchronized(ThreadStates.class){}}});thread.start();//让主线程先获取锁synchronized(ThreadStates.class){//获取线程StateThread.Statestate=thread.getState();//打印线程状态System.out.println("第一次获取线程状态:"+state);//休眠1stry{Thread.sleep(1000);}catch(InterruptedExceptione){e.printStackTrace();}//再次获取线程状态state=thread.getState();//打印线程状态System.out.println("第二次获取线程状态:"+state);}上面程序的执行结果如下图所示:当线程获取到同步锁时,它将从BLOCKED状态变为RUNNABLE状态3、从RUNNABLE到WAITTING线程调用wait()方法后,会从RUNNABLE状态变为WAITING等待状态,没有时间限制,如下图://创建线程Threadthread=newThread(newRunnable(){@Overridepublicvoidrun(){synchronized(this){try{//线程睡眠this.wait();}catch(InterruptedExceptione){e.printStackTrace();}}}});//启动线程thread.start();//获取线程状态Thread.Statestate=thread.getState();//打印线程状态System.out.println("第一次获取线程状态:"+state);//Sleep1stry{Thread.sleep(1000);}catch(InterruptedExceptione){e.printStackTrace();}//获取线程状态state=thread.getState();//打印线程状态System.out.println("第二次获取线程状态:"+state);上面程序的执行结果如下图所示:当调用notify/notifyAll方法时,线程会从WAITING状态变为RUNNABLE状态,如下代码所示:对象锁=newObject();//创建一个线程Threadthread=newThread(newRunnable(){@Overridepublicvoidrun(){synchronized(lock){try{//线程休眠lock.wait();//获取当前线程状态Thread.Statestate=Thread.currentThread().getState();//打印线程状态System.out.println("获取线程状态:"+state);}catch(InterruptedExceptione){e.printStackTrace();}}}});//启动线程thread.start();//获取线程状态Thread.Statestate=thread.getState();//打印线程状态System.out.println("获取线程状态第一次:"+state);//sleep1stry{Thread.sleep(100);}catch(InterruptedExceptione){e.printStackTrace();}//获取线程状态state=thread.getState();//打印线程状态System.out.println("第二次获取线程状态:"+state);//唤醒线程threadsynchronized(lock){lock.notify();}上面程序的执行结果如下图所示:4.从RUNNABLE到TIMED_WATTING当调用一个有超时的等待方法时,比如sleep(xxx),线程会从RUNNABLE状态变为TIMED_WAITING限时状态,如下代码所示://创建线程Threadthread=newThread(newRunnable(){@Overridepublicvoidrun(){try{Thread.sleep(1000);}catch(InterruptedExceptione){e.printStackTrace();}}});//启动线程thread.start();//获取线程状态Thread.Statestate=thread.getState();//打印线程状态System.out.println("获取线程状态第一次:"+state);//sleep1stry{Thread.sleep(100);}catch(InterruptedExceptione){e.printStackTrace();}//获取线程状态state=thread.getState();//printthreadstateSystem.out.println("第二次获取线程状态:"+state);上面程序的执行结果如下图所示:当超过超时时间时,线程会从TIMED_WAITING状态变为RUNNABLE状态,实现代码如下//创建线程Threadthread=newThread(newRunnable(){@Overridepublicvoidrun(){try{Thread.sleep(1000);//获取当前线程状态Thread.Statestate=Thread.currentThread().getState();//打印threadstateSystem.out.println("Getthreadstate:"+state);}catch(InterruptedExceptione){e.printStackTrace();}}});//启动线程thread.start();//获取线程threadstateThread.Statestate=thread.getState();//打印线程状态System.out.println("第一次获取线程状态:"+state);//Sleep1stry{Thread.sleep(100);}赶上(InterruptedExceptione){e.printStackTrace();}//获取线程状态state=thread.getState();//打印线程状态System.out.println("第二次获取线程状态:"+state);上面程序的执行结果如下图所示:5.RUNNABLE到TERMINATED线程执行完后,会从RUNNABLE状态转为TERMINATED销毁状态,如下代码所示://创建一个线程Threadthread=newThread(newRunnable(){@Overridepublicvoidrun(){//获取当前线程状态Thread.Statestate=Thread.currentThread().getState();//打印线程状态System.out.println("获取线程状态:"+state);}});//启动线程thread.start();//等待100ms直到线程执行完毕Thread.sleep(100);//获取线程状态Thread.Statestate=thread.getState();//打印线程状态System.out.println("线程状态:"+state);上面程序的执行结果如下图所示:总结Java中线程的生命周期,有6种:NEW(初始化状态)、RUNNABLE(可运行/运行状态)、BLOCKED(阻塞状态)、WAITING(无限等待状态),TIMED_WAITING(定时等待状态),TERMINATED(终止状态)线程生命周期转换过程如下图所示: