程序员人生 网站导航

[置顶] Java线程状态

栏目:框架设计时间:2015-01-17 09:39:25

线程跟人类1样具有自己的生命周期,1条线程从创建到履行终了的进程即是线程的生命周期,此进程可能在不同时刻处于不同的状态,线程状态正是这小节的主题,线程到底有多少种状态?不同状态之间是如何转化的?

对线程的状态的分类并没有严格的规定,只要能正确表示状态便可,如图2⑸⑺⑴,先看其中1种状态分类,1个线程从创建到死亡可能会经历若干个状态,但在任意1个时间点线程只能处于其中1种状态,总共包括5个状态:新建(new)、可运行(runnable)、运行(running)、非可运行(not runnable)、死亡(dead)。线程的状态的转化可以由程序控制,通过某些API可以到达转化效果,例如Thread类的start、stop、sleep、suspend、resume、wait、notify等方法(stop、suspend、resume等方法由于容易引发死锁问题而早已被弃用)。

图2⑸⑺⑴

 

l   新建(new):1个线程被创建了但未被启动就处于新建状态,即在程序中使用new MyThread();创建的线程实例就处于此状态。

l   可运行(runnable):创建的线程实例调用start()方法后便进入可运行状态,处于此状态的线程其实不是说1定处于运行状态,我们在上1节多线程调度策略了解到Java多线程使用的是抢占式调度,每一个可运行线程轮着获得CPU时间片,可以虚拟想象成有1个可运行线程池,start()方法把线程放进可运行线程池中,CPU按1定规则1个个履行池里的线程。

l   运行(running):当可运行线程获得到CPU履行时间片即进去了运行状态。

l   非可运行(notrunnable):运行中的线程因某种缘由暂时放弃CPU的使用权,多是由于履行了挂起、睡眠或等待等操作,在履行I/O操作时由于外部装备速度远低于处理器速度也可能致使线程暂时放弃CPU使用权,在获得对象的同步锁进程中如果同步锁先被别的线程占用一样可能致使线程暂时放弃CPU。

l   死亡(dead):线程履行完run()方法实现的任务,或由于异常致使退出任务,线程进入死亡状态后将不可再转换成其他状态。

将非可运行(not runnable)状态继续细分,如图2⑸⑺⑵,新建、可运行、运行、死亡4个状态的定义和转化与前面的1样,重点看非可运行状态引伸出来的3个状态:阻塞(blocked)、同步锁(locked)、等待(waiting)。

l   阻塞(blocked):阻塞由阻塞事件触发,线程处于阻塞状态将放弃CPU的使用权,暂时停止运行。1般线程履行了sleep()、join()方法,或发出了I/O要求,线程就将处于阻塞状态,假设sleep()履行的睡眠结束、join()履行的等待中断超时、I/O要求结束,则将重新回到可履行状态,等待分配CPU。

l   同步锁(locked):假设1个线程准备调用1个同步方法,而同步方法对应的对象正被其他线程占用,此时线程就将进入同步锁状态。实际上,Java中的每一个object对象都有1个monitor,此monitor负责对同步域在并发时的独占处理,即1个线程调用某对象的同步方法时,JVM将检测改对象的monitor是不是已被占用,如果没有被占用,线程则得到monitor占有权,继续履行该对象的同步方法,否则线程将被扔进1个等待线程队列排队,直到monitor被释放后,所有等待的线程继续竞争monitor占有权,抢到monitor占有权后才进入可履行状态等待CPU的分配,才有资格履行同步方法。

l   等待(waiting):运行中的线程履行了wait()方法后就进入等待状态。1个对象履行了wait()方法一样将使线程进入该对象的等待线程队列,同时它还将释放对象锁,即放弃monitor的占有权。只有在其他线程中对该对象调用notify()、notifyAll()方法时才会唤醒等待线程队列中的线程,notify是随机唤醒等待队列中的1个线程,而nofityAll则是唤醒所有等待队列中的线程,所有线程被唤醒后将对该对象的monitor占有权竞争,获得到占有权的线程才能转化为可履行状态,等待分配CPU往下履行,其他线程则继续等待。

 

图2⑸⑺⑵

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐