线程的生命周期

目录

一、通用的java生命周期

​ 线程的生命周期通常有五种状态。这五种状态分别是:新建状态、就绪状态、运行状态、阻塞状态和死亡状态

新建状态:指的是线程已经被创建,但是还不允许分配 CPU 执行。
就绪状态: 指的是线程可以分配 CPU 执行。在这种状态下,真正的操作系统线程已经被成功创建了,所以可以分配 CPU 执行。
运行状态:当有空闲的 CPU 时,操作系统会将其分配给一个处于可运行状态的线程,被分配到 CPU 的线程的状态就转换成了运行状态。
阻塞状态:运行状态的线程如果调用一个阻塞的 API(例如以阻塞方式读文件)或者等待某个事件(例如键盘输出Scanner方法调用),那么线程的状态就会转换到阻塞状态,同时释放 CPU 使用权,阻塞状态的线程永远没有机会获得 CPU 使用权。当等待的事件出现了,阻塞状态结束,线程就会从阻塞状态转换到就绪状态,重新抢到CPU时间片!
死亡状态:线程执行完或者出现异常就会进入死亡状态,死亡状态的线程不会切换到其他任何状态,进入死亡状态也就意味着线程的生命周期结束了。通常线程死亡的方式有三种:

  1. run()方法执行完成,线程正常结束。
  2. 线程抛出一个未捕获的Exception或Error。
  3. 直接调用该线程的stop()方法来结束该线程——该方法容易导致死锁,通常不推荐使用。

二、线程的方法

1、sleep(long millis)线程休眠

线程休眠:让执行的线程暂停一段时间,进入等待状态。
static void sleep(long millis):调用此方法后,当前线程放弃 CPU 资源,在指定的时间内,sleep 所在的线程不会获得可运行的机会,此状态下的线程不会释放同步锁。
该方法更多的是用来模拟网络延迟,让多线程并发访问同一资源时的错误效果更加明显。

2.wait()线程等待

线程等待:一旦一个线程执行到wait(),就释放当前的锁。
注意:此方法必须在同步代码块或同步方法中

3、notify()/notifyAll()

唤醒:唤醒wait的一个或所有的线程,需和wait()成对使用

4、join()

联合线程:表示这个线程等待另一个线程完成后(死亡)才执行,join 方法被调用之后,线程对象处于阻塞状态。写在哪个线程中,哪个线程阻塞

这种也称为联合线程,就是说把当前线程和当前线程所在的线程联合成一个线程

5、yield()

礼让线程:表示当前线程对象提示调度器自己愿意让出 CPU 资源。

    调用该方法后,线程对象进入就绪状态,所以完全有可能:某个线程调用了 yield() 方法,但是线程调度器又把它调度出来重新执行。

sleep() 和 yield() 方法的区别:

  ①都能使当前处于运行状态的线程放弃 CPU资源,把运行的机会给其他线程

  ②sleep 方法会给其他线程运行的机会,但是不考虑其他线程优先级的问题;yield 方法会优先给更高优先级的线程运行机会

  ③调用 sleep 方法后,线程进入计时等待状态,调用 yield 方法后,线程进入就绪状态。