【多线程】图解线程生命周期

1. 线程有哪6种状态?

  • New:新建,已经创建尚未启动,未执行start()
  • Runnable:可运行的,调用start()方法之后;一旦线程调用了start()方法,线程就会进入Runnable状态。 对应操作系统中的readyrunning
  • Blocked:当一个线程进入被synchronized修饰的代码后,并且该锁已经被其它线程占用。
  • Waiting:没有设置timeout的Object.wait()方法;
  • Timed Waiting: 对于TIMED_WAITING状态而言,即使没到超时时间,收到Object.notify() Object.notifyAll() LockSuppory.unpark()也会被唤醒。
  • Terminated:线程正常结束;出现没有被捕获的异常导致意外终止run()方法。

2. 每个状态是什么含义?

在代码中演示BLOCKEDWAITINGTIMED_WAITING状态

/**
 * 展示Blocked、Waiting、TimedWaiting
 * */
public class BlockedWaitingTimedWaiting implements Runnable{

    public static void main(String[] args) throws InterruptedException {

       BlockedWaitingTimedWaiting block = new BlockedWaitingTimedWaiting();

       Thread thread1 = new Thread(block);

       thread1.start();

       Thread thread2 = new Thread(block);

       thread2.start();

       Thread.sleep(100);

       //打印出Timed_waiting状态,因为正在执行Thread.sleep(1000)
       System.out.println(thread1.getState());//①
       //打印出Blocked状态,因为thread2想拿到sync()的锁却拿不到
       System.out.println(thread2.getState());//②

       Thread.sleep(2300);//③
       System.out.println(thread1.getState());//④
       System.out.println(thread2.getState());//⑤
       System.out.println(thread1.getState());//⑥
       System.out.println();

    }

    @Override
    public void run() {
        sync();//⑦

    }

    private synchronized void sync(){
        try {
            Thread.sleep(2000);//⑧
            wait();//⑨
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

输出结果:

TIMED_WAITING
BLOCKED
WAITING
TIMED_WAITING
WAITING


Process finished with exit code 130

输出结果分析:

①和②行的输出结果注释已给出,④为什么会输出WAITING状态?因为thread1已经执行完⑧,正在执行wait(),执行wait()方法时线程处于WAITING状态。那⑤呢?④正在执行synchronized代码块,⑤为什么会输出TIMED_WAITING?根据Oracle官网说明:

Note that the wait method, as it places the current thread into the wait set for this object, unlocks only this object; any other objects on which the current thread may be synchronized remain locked while the thread waits.

请注意,wait 方法将当前线程放入此对象的等待集中,因此仅解锁此对象; 当前线程可能同步的任何其他对象在线程等待时保持持锁状态。

也就是说wait()方法会释放当前线程持有的对象锁,所以⑤会执行同步代码块。

至于⑥,没有唤醒该线程的处理,所以一直处于WAITING状态。

3. 状态间的转换图示

在这里插入图片描述

状态转换的特殊情况
  • Object.wait()状态刚被唤醒时,通常不能立刻抢到monitor锁,那就会从Waiting先进入到Blocked状态,抢到锁再转换到Runnable状态。
  • 如果异常发生,可以直接跳到终止Terminated状态,不必再遵循路径,比如可以从Waiting直接到Terminated状态。

BLOCKED

public static final Thread.State BLOCKED

Thread state for a thread blocked waiting for a monitor lock. A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling Object.wait.

关于唤醒wait()方法,Orcale官网还增加了一种方式:

This method causes the current thread (call it T) to place itself in the wait set for this object and then to relinquish any and all synchronization claims on this object. Thread T becomes disabled for thread scheduling purposes and lies dormant until one of four things happens(当前线程因线程调度目的而处于禁用状态并且休眠直到以下四件事任一发生):

  • Some other thread invokes the notify method for this object and thread T happens to be arbitrarily chosen as the thread to be awakened.
  • Some other thread invokes the notifyAll method for this object.
  • Some other thread interruptsthread T.
  • The specified amount of real time has elapsed, more or less. If timeout is zero, however, then real time is not taken into consideration and the thread simply waits until notified.

4. 阻塞状态是什么?

一般习惯而言,把Blocked(被阻塞)、waiting(等待)、TimedWaiting(计时等待)都称为阻塞状态。

不仅仅是Blocked

5. 常见面试问题

  • 线程的有哪几种状态?生命周期是什么?
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java多线程生命周期包括以下几个状态: 1. 新建状态(New):当创建一个Thread对象时,线程处于新建状态。此时线程还没有开始执行,也没有分配到系统资源。 2. 就绪状态(Runnable):当调用线程的start()方法后,线程进入就绪状态。此时线程已经分配到了系统资源,但还没有开始执行。在就绪状态下,线程等待获取CPU的执行时间片。 3. 运行状态(Running):当线程获取到CPU的执行时间片后,线程进入运行状态。此时线程正在执行任务。 4. 阻塞状态(Blocked):在某些情况下,线程可能会被阻塞,例如等待某个资源的释放或者等待输入输出操作完成。当线程处于阻塞状态时,它暂时停止执行,直到满足某个条件后才能继续执行。 5. 等待状态(Waiting):线程进入等待状态是因为调用了wait()方法、join()方法或者LockSupport.park()方法。在等待状态下,线程会释放持有的锁,并且暂停执行,直到被唤醒或者超时。 6. 超时等待状态(Timed Waiting):线程进入超时等待状态是因为调用了带有超时参数的sleep()方法、wait()方法、join()方法或者LockSupport.parkNanos()方法。在超时等待状态下,线程会暂停执行,直到被唤醒、超时时间到达或者被中断。 7. 终止状态(Terminated):线程执行完任务或者发生异常后,线程进入终止状态。此时线程已经结束执行,不会再被调度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值