清楚的理解和认知线程状态是java多线程的基础,多线程本质上其实就是管理多个线程的状态,以期在保证线程安全的情况下获得最佳的运行效率(发挥cpu的最佳效能)
首先列举几个容易混淆的线程状态问题文末进行解答:
1Java线程有几种状态
2.线程sleep之后处于什么状态
3.A线程被sychnolozy锁阻塞了,B线程被lock锁阻塞了 AB两个线程是否处于相同状态是什么状态
4.当java线程发生IO阻塞时 线程处于什么状态:
5.java线程和操作系统线程状态是如何对应的:
java线程状态:
- 初始状态
实现Runnable接口和继承Thread可以得到一个线程类,new一个实例出来,线程就进入了初始状态。
2可运行状态
2.1. 就绪状态
就绪状态只是说你资格运行,调度程序没有挑选到你,你就永远是就绪状态。
调用线程的start()方法,此线程进入就绪状态。
当前线程sleep()方法结束,其他线程join()结束,等待用户输入完毕,某个线程拿到对象锁,这些线程也将进入就绪状态。
当前线程时间片用完了,调用当前线程的yield()方法,当前线程进入就绪状态。
锁池里的线程拿到对象锁后,进入就绪状态。
2.2. 运行中状态
线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一一种方式。
3. 阻塞状态
阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态。
4. 等待
处于这种状态的线程不会被分配CPU执行时间,它们要等待被显式地唤醒,否则会处于无限期等待的状态。
5. 超时等待
处于这种状态的线程不会被分配CPU执行时间,不过无须无限期等待被其他线程显示地唤醒,在达到一定时间后它们会自动唤醒。
6. 终止状态
当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它终止了。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦终止了,就不能复生。
在一个终止的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。
操作系统线程状态:
操作系统中的线程除去new和terminated状态,一个线程真实存在的状态,只有:
ready :表示线程已经被创建,正在等待系统调度分配CPU使用权。
running:表示线程获得了CPU使用权,正在进行运算
waiting:表示线程等待(或者说挂起),让出CPU资源给其他线程使用(操作系统该状态应该是阻塞)
为什么没有new和terminated状态?是因为这两种状态实际上并不存在于线程运行中,所以也没什么实际讨论的意义。
操作系统线程与java线程状态的对应:
问题解答:
1Java线程有几种状态: 六种而不是五种容易漏掉TIMEWAITING状态,操作系统线程状态可以说是五种也可以说三种(排除新建和终止)
2.线程sleep之后处于什么状态:timewaiting
3.A线程被sychnolozy锁阻塞了,B线程被lock锁阻塞了 AB两个线程是否处于相同状态是什么状态:
sych锁是blocked状态,blocked状态只能从sych锁进入无其他方式
lock锁的阻塞是waiting或timewaiting状态
4.当java线程发生IO阻塞时 线程处于什么状态:
rannable状态,当io阻塞时一定处于操作系统线程状态的waiting状态,操作系统的waiting状态的定义是:表示线程等待(或者说挂起),让出CPU资源给其他线程使用。java线程种 waiting、timewaiting、blocked都必然处于操作系统线程waiting状态、rannable则有可能处于waiting状态。IO阻塞在java的定义中就是rannable状态只不过让出了cpu资源。
5.java线程和操作系统线程状态是如何对应的:
见上图表格
Java线程状态中blocked、waiting、time waiting都是waiting状态,runnable线程在没有获得cpu资源的时候也是waiting状态 rannable状态包含了操作系统的ready和running状态