面试题总结:线程的周期

在线程的生命周期中,它要经过新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)五种状态。当线程start后,它不能一直"独占"着CPU独自运行,所以CPU需要在多条线程之间切换,于是线程状态也会多次在运行、阻塞之间切换。

    新建 New 就绪 Runnable 运行 Running 阻塞 Blocked 死亡 Dead

发生以下情况时,线程将进入阻塞状态:

    调用sleep()方法时,此时会放弃它所占用的处理器资源(过了sleep指定时间不再阻塞) 调用一个阻塞式IO方法还没有返回之前,该线程被阻塞(阻塞IO方法返回后不再阻塞) 试图获取一个正被其它线程所持有的同步监视器(拿到监听器不再阻塞) 等待通知时(notify)(其它线程调用了notify时不再阻塞) 调用suspend()方法将程序挂起时(线程调用resume()方法时撤销挂起时不再阻塞)

线程死亡情况:

    线程正常结束(run或call方法执行完毕) 线程抛出一个未捕获的Exception或Error 线程自己调用stop()方法(该方法容易导致死锁)

PS:

    如果直接调用run()方法,系统会把该线程对象当成普通对象。 如果直接调用了run()方法,则该线程不再处于新建状态,不能再次调用start()方法,否则会报IllegalThreadStateException异常 如果直接调用了run()方法,则在run()方法里不能直接通过this.getName()方法获得线程名。

线程同步以及线程调度相关的方法

wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁;
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理InterruptedException异常;
notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM 确定唤醒哪个线程,而且与优先级无关;
notityAll():唤醒所有处于等待状态的线程,该方法并不是将对象的锁给所有线程,而是让它们竞争,只有获得锁的线程才能进入就绪状态;

链接:

经验分享 程序员 微信小程序 职场和发展