面试官:说说Java线程的生命周期

咱们知道线程是操做系统可以进行运算调度的最小单位,在java中的线程其实就是对操做系统的中的线程进行了封装。java

咱们今天就来讲说Java线程的生命周期,也就线程的生老病死!面试

Java的线程生命周期有六种状态:并发

  1. New(初始化状态)分布式

  2. Runnable(可运行/运行状态)工具

  3. Blocked(阻塞状态)性能

  4. Waiting(无时间限制的等待状态)操作系统

  5. Timed_Waiting(有时间限制的等待状态)线程

  6. Terminated(终止状态)cdn

1.New(初始化状态):指的是在高级语言,好比Java。在Java层面的线程被建立了,而在操做系统中的线程实际上是还没被建立的,因此这个时候是不可能分配CPU执行这个线程的!因此这个状态是高级语言独有的,操做系统的线程没这个状态。咱们New了一个线程,那时候它就是这个状态。blog

2.Runnable(可运行/运行状态):这个状态下是能够分配CPU执行的,在New状态时候咱们调用start()方法后线程就处于这个状态。

3.Blocked(阻塞状态): 这个状态下是不能分配CPU执行的,只有一种状况会致使线程阻塞,就是synchronized!咱们知道被synchronized修饰的方法或者代码块同一时刻只能有一个线程执行,而其余竞争锁的线程就从Runnable到了Blocked状态!当某个线程竞争到锁了它就变成了Runnable状态。

注意并发包中的Lock,是会让线程属于等待状态而不是阻塞,只有synchronized是阻塞。(感受是历史遗留问题,不必多一个阻塞状态和等待没差啊)

4.Waiting(无时间限制的等待状态): 这个状态下也是不能分配CPU执行的。有三种状况会使得Runnable状态到waiting状态

1.调用无参的Object.wait()方法。等到notifyAll()或者notify()唤醒就会回到Runnable状态。

2.调用无参的Thread.join()方法。也就是好比你在主线程里面创建了一个线程A,调用A.join(),那么你的主线程是得等A执行完了才会继续执行,这是你的主线程就是等待状态。

3.调用LockSupport.park()方法。LockSupport是Java6引入的一个工具类Java并发包中的锁都是基于它实现的,再调用LocakSupport.unpark(Thread thread),就会回到Runnable状态。

5.Timed_Waiting(有时间限制的等待状态): 其实这个状态和Waiting就是有没有超时时间的差异,这个状态下也是不能分配CPU执行的。有五种状况会使得Runnable状态到waiting状态。

  1. Object.wait(long timeout)。

  2. Thread.join(long millis)。

  3. Thread.sleep(long millis)。注意Thread.sleep(long millis, int nanos) 内部调用的其实也是Thread.sleep(long millis)。

  4. LockSupport.parkNanos(Object blocked,long deadline)。

  5. LockSupport.parkUntil(long deadline)。

6.Terminated(终止状态): 在咱们的线程正常run结束以后或者run一半异常了就是终止状态!

注意有个方法Thread.stop()是让线程终止的,可是这个方法已经被废弃了,不推荐使用,由于好比你这个线程获得了锁,你stop了以后这个锁也随着没了,其它线程就都拿不到这个锁了!这不玩完了么!因此推荐使用interrupt()方法。

interrupt()会使得线程Waiting和Timed_Waiting状态的线程抛出 interruptedException异常,使得Runnabled状态的线程若是是在I/O操做会抛出其它异常。

若是Runnabled状态的线程没有阻塞在I/O状态的话,那只能主动检测本身是否是被中断了,使用isInterrupted()。


若有错误欢迎指正!

我的公众号:yes的练级攻略

有相关面试进阶(分布式、性能调优、经典书籍pdf)资料等待领取

相关文章
相关标签/搜索