1 线程
传送门:线程介绍
2 完整生命周期
线程完整生命周期如下图所示。
由图可知,线程从出生到销毁分为四个阶段,对应四个状态,
分别为:新建、可运行、运行中和销毁状态,
其中,由可运行到运行状态切换是核心。
2.1 New
实例化线程类,申请线程所需的资源,此时线程为新建状态,尚未被启动。
最简单的新建线程样例如下,是的,简单,粗暴,有兴趣可以使用线程池。
Thread thread = new Thread();
2.2 Runnable
线程就绪。
等待CPU分配资源执行线程中的任务,
此时线程进入CPU资源分配队列。
thread.start();
2.3 Running
线程运行。
线程得到CPU资源,运行线程中的任务,此时线程处于运行状态。
运行中的线程可以通过手动配置方式,进入就绪状态。
2.3.1 运行->就绪
- yield()
线程让出资源。线程由运行状态直接进入就绪状态,释放CPU资源,将CPU执行权让给相同或优先级更高的线程,这就导致并不能保证其他线程一定能获得执行权,可能是当前线程重新获取CPU资源,进入运行状态。
2.3.2 线程运行->阻塞
- sleep()
线程休眠。正在运行的线程释放CPU资源,但没有让出持有的对象资源,当休眠结束,等待CPU分配资源,继续执行任务。 - join()
等待其他线程终止。当前线程中调用另一个线程的join()方法,当前线程进入阻塞状态,直到另一个线程执行结束,当前线程由阻塞进入就绪状态。 - wait()
线程等待,释放线程持有的资源。进入等待的线程无法自动唤醒,需要手动通知,如notify()或notifyAll()。 - synchronized
同步阻塞,对当前线程持有对象加同步锁,其他线程申请对象资源时,进入等待,直到该线程执行结束,释放资源。
2.4 Blocked
线程阻塞,即线程此时让出占有的CPU资源,线程挂起,进入阻塞状态,主动进入阻塞状态的方法:
阻塞->就绪
- notify()
唤醒等待的线程,线程进入就绪态,等待CPU分配运行资源。 - notifyAll()
唤醒所有等待的线程,线程进入就绪态,等待CPU分配运行资源。
2.5 Dead
线程销毁。线程自动执行结束或被其他线程终结,此时线程销毁,释放资源。
- 自动销毁
线程执行所有任务,自动销毁。 - 手动销毁:interrupt
退出线程,线程销毁。
推荐使用interrrupt方法,另一种方法stop,但是被标记为@Deprecated,不推荐是使用。
interrupt方法源码如下图所示,
由注释可知,方法interrupt方法功能即中断这个线程。
当前线程在中断前会一直运行,
线程调用checkAccess方法时,可能会抛出SecurityException异常,checkAccess方法检测当前运行中的线程是否有权限修改线程状态。
如果该线程在调用wait()、wait(long)或wait(long, int)方法时阻塞住,或者调用join()、join(long)、sleep(long)或者sleep(long, int)方法阻塞,interrrupt方法会清除,并接受InterrruptException。
而stop方法,源码如下图所示,
由注释可知,stop方法是不安全的,
通过stop方法停止线程会导致所有已加锁的监听器解锁。
3 小结
(1)线程完整生命周期:新建、可运行、运行中和销毁四个阶段;
(2)线程状态转换方法:yield、sleep、join、wait等;
(3)中断线程通过interrupt方法,stop方法不安全,会导致已锁的监听器释放锁。