一、线程状态概述
当线程被创建并启动以后 它既不是一启动就进入了执行状态 也不是一直处于执行状态 在线程的生命周期中有很多种状态:
New(新建状态) 线程刚被创建 但是并未启动 还没调用start方法
Runnable(可运行状态)线程可以在java虚拟机中运行的状态 可能正在运行自己的代码 也可能没有
Blocked(锁阻塞状态) 当一个线程试图获取一个对象锁 而该对象锁被其他的线程持有 则该线程进入Blocked状态
当该线程持有锁时 该线程将变成Runnable状态
Waiting(无限等待状态) 一个线程在等待另一个线程执行一个(唤醒)动作时 该线程进入Waiting状态
进入这个状态后是不能自动唤醒的 必须等待另一个线程调用notify或者notifyAll方法才能够唤醒
TimedWaiting(计时等待状态) 同waiting状态 有几个方法有超时参数 调用他们将进入Timed Waiting状态
这一状态将一直保持到超时期满或者接收到唤醒通知 带有超时参数的常用方法有Thread.sleep()和Object.wait()
Teminated(终止状态) 因为run方法正常退出而死亡 或者因为没有捕获的异常终止了run方法而死亡
小案例:以包子铺为例
★ 分析:
【壹】、TimedWaiting(计时等待状态)
一个正在限时等待另一个线程执行一个(唤醒)动作的线程处于这一状态
当调用了sleep方法之后 当前执行的线程就进入到“休眠状态” 其实就是所谓的Timed Waiting(计时等待)
1. 进入Timed Waiting状态的一种常见情形是调用sleep()方法 单独的线程也可以调用 不一定非要有协作关系
2. 为了让其他线程有机会执行 可以将Thread.sleep()的调用放线程run()之内 这样才能保证该线程执行过程中会睡眠
3. sleep与锁无关 线程睡眠到期自动苏醒 并返回到Runnable(可运行)状态
【贰】、Blocked(锁阻塞状态)
一个正在阻塞等待一个监视器锁对象的线程处于这一状态。
这个状态非常好理解 比如线程A与线程B代码中使用同一个锁 如果线程A获
取到锁 线程A进入到Runnable状态 那么线程B就进入到Blocked锁阻塞状态
【叁】、Waiting(无限等待状态)
一个正在无限期等待另一个线程执行一个特别的唤醒动作的线程处于这一状态
线程之间的通信:
比如说 有一个包子店 一个顾客要来买包子
顾客和老板说明买的包子的种类和数量
然后等着老板做包子(此时调用wait()方法) 进入Waiting状态 无限等待 因为不知道老板要做多久的包子
然后老板做好了包子 唤醒顾客(此时调用notify()方法)
告诉顾客包子做好了 可以吃了
★ 代码实现
public class WaitAndNotify {
public static void main(String[] args) {
// 创建锁对象 保证唯一
Object object=new Object();
//创建顾客线程
new Thread()
{
@Override
public void run() {
// 使用同步技术 保证等待和唤醒只能有一个在执行
synchronized (object)
{
System.out.println("老板 我要10个肉包");
try {
//等待
object.wait();