【搞定Java并发编程】第1篇:线程的五种可用状态

本文转载自牛客网上一网友的回答:概括的解释下线程的几种可用状态

第一种状态:新建(new)新建了一个线程对象。例如,Thread thread = new Thread();

第二种状态:可运行状态(Runnable)又叫“就绪状态”。线程新建后,其他线程(比如main线程)调用了该对象的start()方法,从而来启动该线程。Runnable状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权;

第三种状态:运行状态(Running)可运行状态(Runnable)的线程获得了CPU时间片(timeslice),执行代码。需要注意的是,线程只能从就绪状态进入到运行状态;

第四种状态:阻塞状态(Block)阻塞状态是指线程因为某种原因放弃了CPU使用权,即让出了CPU TimeSlice,暂时停止运行。直到线程重新进入可运行(Runnable)状态,才有机会再次获得CPU TimeSlice转到运行(Running)状态。阻塞的情况有三种:

1、等待阻塞:运行(Running)的线程执行wait()方法,JVM会把该线程放入等待队列(waiting  queue)中;

2、同步阻塞:运行(Running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程先放入锁池(lock  pool)中;

3、其他阻塞:运行(RunnIng)的线程执行Thread.sleep()方法或者t.join()方法,或者发出I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(Runnable)状态。

第五种状态:死亡(Dead):线程run()方法和main()方法执行结束、或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程是不可再次重生的。


另一位牛友的比喻回答:

可以用早起坐地铁来比喻这个过程:

还没起床:sleeping

起床收拾好了,随时可以坐地铁出发:Runnable

等地铁来:Waiting

地铁来了,但要排队上地铁:I/O阻塞

上了地铁,发现暂时没座位:synchronized阻塞

地铁上找到座位:Running

到达目的地:Dead


比较重要的几点需要注意:

1 sleep和yield的区别在于, sleep可以使优先级低的线程得到执行的机会,  而yield只能使同优先级的线程有执行的机会;

2 interrupt方法不会中断一个正在运行的线程.就是指线程如果正在运行的过程中, 去调用此方法是没有任何反应的. 为什么呢, 因为这个方法只是提供给 被阻塞的线程, 即当线程调用了.Object.wait, Thread.join, Thread.sleep三种方法之一的时候, 再调用interrupt方法, 才可以中断刚才的阻塞而继续去执行线程;

3 join()  当join(0)时等待一个线程执行直到它死亡返回主线程,  当join(1000)时主线程等待一个线程1000纳秒,后回到主线程继续执行;

4 waite()和notify()必须在synchronized函数或synchronized  block中进行调用。如果在non-synchronized函数或non-synchronized  block中进行调用,虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。


这5种状态涉及到的内容包括Object类, Thread和synchronized关键字。

Object类,定义了wait(), notify(), notifyAll()等休眠/唤醒函数。

Thread类,定义了一些列的线程操作函数。例如,sleep()休眠函数, interrupt()中断函数, getName()获取线程名称等。

synchronized,是关键字;它区分为synchronized代码块和synchronized方法。synchronized的作用是让线程获取对象的同步锁。

在后面详细介绍wait(),notify()等方法时,我们会分析为什么“wait(), notify()等方法要定义在Object类,而不是Thread类中”。


参考及推荐

1、牛客网:概括的解释下线程的几种可用状态

2、Java多线程系列--“基础篇”01之 基本概念http://www.cnblogs.com/skywang12345/p/3479024.html

猜你喜欢

转载自blog.csdn.net/pcwl1206/article/details/84671759