当前位置: 首页 > 后端技术 > Java

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

时间:2023-04-01 23:33:03 Java

线程的生命周期是指一个线程从创建到销毁的整个过程。线程的生命周期一般有五种:初始状态、可运行状态、运行状态、休眠状态、终止状态,它们的状态转换如下图所示:Java线程生命周期Java线程的生命周期不同从上面提到的生命周期。它有以下6种状态: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,如下代码所示://创建线程Thread线程=newThread(newRunnable(){@Overridepublicvoidrun(){//获取当前正在执行的线程ThreadcurrThread=Thread.currentThread();//获取线程状态Thread.Statestate=currThread.getState();//打印线程状态System.out.println(state);}});thread.start();上述程序的执行结果如下图所示: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{//线程休眠锁.等待();//获取当前线程状态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=线程。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(IninterruptedExceptione){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);上面程序的执行结果如下图所示:当超时时间到时,线程会从TIMED_WAITING状态变为RUNNABLE状态,实现代码如下://创建一个线程Threadthread=newThread(newRunnable(){@Overridepublicvoidrun(){try{Thread.sleep(1000);//获取当前线程状态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);上面程序的执行结果如下图所示:5.RUNNABLE到TERMINATED线程执行完后,会从RUNNABLE状态变为TERMINATED并被销毁状态,如下代码所示://创建一个线程Threadthread=newThread(newRunnable(){@Overridepublicvoidrun(){//获取当前线程状态Thread.Statestate=Thread.currentThread().getState();//打印线程状态System.out.println("Getthreadstatus:"+state);}});//启动线程thread.start();//等待100ms直到线程执行完Thread.sleep(100);//获取线程状态Thread.Statestate=thread.getState();//打印线程状态System.out.println("Threadstate:"+state);上面程序的执行结果如下图所示:总结Java线程生命周期有6种类型:NEW(初始化状态)、RUNNABLE(可运行/运行状态)、BLOCKED(阻塞状态)、WAITING(无限等待状态),TIMED_WAITING(定时等待状态),TERMINATED(终止状态)线程生命周期的转换过程如下图所示:参考资料《Java并发编程实战》是非自评,名誉自评在别人看来,得失是用数字来计算的。公众号:Java面试真题分析面试合集:https://gitee.com/mydb/interview