线程状态概述
当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。在线程的生命周期中, 有几种状态呢?在
java.lang.Thread.State 这个枚举中给出了六种线程状态:
线程状态
|
导致状态发生条件
|
NEW(
新建
)
|
线程刚被创建,但是还没调用start方法,并未启动。
|
Runnable(可运行
)
|
线程可以在
java虚拟机中运行的状态,可能正在运行自己代码,也可能没有,这取决于操作系统处理器。
|
Blocked(锁阻塞
)
|
当一个线程试图获取一个对象锁,而该对象锁被其他的线程持有,则该线程进入
Blocked
状
态;当该线程持有锁时,该线程将变成
Runnable
状态。
|
Waiting(无限等待
)
|
一个线程在等待另一个线程执行一个(唤醒)动作时,该线程进入
Waiting
状态。进入这个
状态后是不能自动唤醒的,必须等待另一个线程调用
notify
或者
notifyAll
方法才能够唤醒。
|
Timed Waiting(计时等待
)
|
同
waiting
状态,有几个方法有超时参数,调用他们将进入
Timed Waiting状态。这一状态 将一直保持到超时期满或者接收到唤醒通知。带有超时参数的常用方法有
Thread.sleep
、
Object.wait
。
|
Teminated(被终止
)
|
因为
run
方法正常退出而死亡,或者因为没有捕获的异常终止了
run
方法而死亡。
|
Timed Waiting(计时等待)
Timed Waiting
在
API
中的描述为:一个正在限时等待另一个线程执行一个(唤醒)动作的线程处于这一状态。
为了让其他线程有机会执行,可以将
Thread.sleep()
的调用
放线程
run()
之内。这样才能保证该线程执行过程中会睡眠。
sleep
与锁无关,线程睡眠到期自动苏醒。
sleep()
中指定的时间是线程不会运行的最短时间。因此,
sleep()
方法不能保证该线程睡眠到期后就
开始立刻执行。
BLOCKED(锁阻塞)
Blocked
状态在
API
中的介绍为:一个正在阻塞等待一个监视器锁(锁对象)的线程处于这一状态。
比如,线程
A
与线程
B
代码中使用同一锁,如果线程
A获取到锁,线程
A
进入到
Runnable
状态,那么线程
B
就进入到
Blocked
锁阻塞状态。
Waiting(无限等待)
Wating
状态在
API
中介绍为:一个正在无限期等待另一个线程执行一个特别的(唤醒)动作的线程处于这一状态。
当多个线程协作时,比如
A
,
B
线程,如果
A
线程在
Runnable
(可运行)状态中调用了
wait()
方法那么
A线程就进入 了
Waiting
(无限等待)状态,同时失去了同步锁。假如这个时候
B线程获取到了同步锁,在运行状态中调用了notify()
方法,那么就会将无限等待的
A
线程唤醒。
注意是唤醒,如果获取到锁对象,那么A线程唤醒后就进入 Runnable(可运行)状态;如果没有获取锁对象,那么就进入到Blocked(锁阻塞状态)。
什么是线程通信、如何实现?
所谓线程通信就是线程间相互发送数据,线程间共享一个资源即可实现线程通信。
线程通信常见形式
通过共享一个数据的方式实现。
根据共享数据的情况决定自己该怎么做,以及通知其他线程怎么做。
线程通信实际应用场景
生产者与消费者模型:生产者线程负责生产数据,消费者线程负责消费生产者产生的数据。
要求:生产者线程生产完数据后唤醒消费者,然后进入等待状态,消费者消费完该数据后唤醒生产者,然后进入等待状态。
线程通信案例模拟
模拟客服系统,系统可以不断的接入电话 和 分发给客服。
线程通信的前提:线程通信通常是在多个线程操作同一个共享资源的时候需要进行通信,且要保证线程安全。
Object类的等待和唤醒方法
注意 上述方法应该使用当前同步锁对象进行调用。