温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

java线程有多少种状态

发布时间:2022-03-19 16:59:03 来源:亿速云 阅读:147 作者:iii 栏目:大数据

这篇文章主要介绍“java线程有多少种状态”,在日常操作中,相信很多人在java线程有多少种状态问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”java线程有多少种状态”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

线程有哪 6 种状态?

人有生老病死。同样的,线程有自己的生命周期。在 Java 中线程的生命周期中一共有 6 种状态:

  • New(新创建)

  • Runnable(可运行)

  • Blocked(被阻塞)

  • Waiting(等待)

  • Timed Waiting(计时等待)

  • Terminated(被终止)

查看 Thread 类的源码时,内部还定义了这样一个枚举类。这个枚举类定义的就是线程的状态,源码如下:

public enum State {
       
        NEW,

        RUNNABLE,

        BLOCKED,

        WAITING,

        TIMED_WAITING,

        TERMINATED;
}

PS:线程在任何时刻只可能处于以上 6 种的其中 1 种状态,我们可以调用 getState () 查看线程的状态

线程是如何切换状态的?

我们知道线程有 6 种状态。然而,它是如何切换的呢?狗哥根据自己的理解做了一张图,接下来将根据这张图详细了解下线程状态的切换。

java线程有多少种状态

线程的 6 种状态

NEW (新创建)

先注意 NEW 状态:线程被 NEW 出来,但还没调用 start 方法时,就处于这种状态。一旦调用了 start 方法也就进入了 RUNNABLE 状态。

RUNNABLE(可运行)

处于 RUNNABLE 的线程,比较特殊。它还分两种状态:Running 和 Ready。也就是说,Java 中处于 Runnable 状态的线程有可能正在执行,也有可能没有正在执行,正在等待被分配 CPU 资源

因此,我们可以推断出,一个处于 Runnable 状态的线程,当它运行到任务的一半时,执行该线程的 CPU 被调度去做其他事情,则该线程暂时不运行。但是,它的状态依然不变,还是 Runnable,因为它有可能随时被调度回来继续执行任务

也就是说:处于 Runnable 状态的线程并不一定在运行。这点在面试中常问,小伙伴们要注意了。

Blocked(被阻塞)

再来看看最简单的 Blocked 状态,从 Runnable 进入 Blocked 只有一种可能:就是进入 synchronized 关键字保护的代码,但是没有获取到 monitor 锁

java线程有多少种状态

线程的 6 种状态

再来,看图的右侧,Blocked ----> Runnable 状态:当处于 Blocked 状态的线程获取到锁

Waiting (等待)

线程从 Runnable 进入 Waiting 状态,有三种可能性:

  • 没有设置 Timeout 参数的 Object.wait () 方法。

  • 没有设置 Timeout 参数的 Thread.join () 方法。

  • LockSupport.park () 方法。

上面我们知道,线程进入 Blocked 状态只可能是:进入 synchronized 保护的代码,但是没获取到 monitor 锁。然而,Java 中还有很多锁,比如:ReentrantLock。线程在获取这种锁时,没有抢到就会进入 Waiting 状态,因为它本质上是调用了 LockSupport.park () 方法。

同样的,调用 Object.wait () 和 Thread.join () 也会让线程进入等待状态

Blocked 与 Waiting 的区别是:Blocked 在等待其他线程释放 monitor 锁,而 Waiting 则是在等待某个条件,比如 join 的线程执行完毕,或者是 notify ()/notifyAll ()

java线程有多少种状态

线程的 6 种状态

看 Waiting 右侧,Waiting ----> Runnable:1、当执行了 LockSupport.unpark (),2、join 的线程运行结束,3、被中断

看 Waiting 右侧,Waiting ----> Blocked:我们看图可以知道其他线程调用 notify () 或 notifyAll () 来唤醒处于 Waiting 的线程,它会直接进入 Blocked 状态。这是为什么?

其他线程能调用 notify () 或 notifyAll () 试图唤醒 Waiting 状态线程,说明必须持有同一个 monitor 锁,也就是说处于 Waiting 的线程被唤醒后并不能马上抢到 monitor 锁,所以它必须先进入 Blocked 状态。而唤醒它的线程执行完毕释放锁后,它能抢到锁就从 Blocked 进入 Runnable 状态

Timed Waiting(计时等待)

这种状态与 Waiting 状态的区别在于:有没有时间限制,Timed Waiting 会等待超时,由系统自动唤醒,或者在超时前被唤醒信号唤醒

有以下 5 种情况会让线程进入 Timed Waiting 状态:

  • 设置 Timeout 参数的 Thread.sleep (time) 方法。

  • 设置 Timeout 参数的 Object.wait (time) 方法。

  • 设置 Timeout 参数的 Thread.join (time) 方法。

  • 设置 Timeout 参数的 LockSupport.parkNanos (long nanos) 方法。

  • 设置 Timeout 参数的 LockSupport.parkUntil (long deadline) 方法。

java线程有多少种状态

线程的 6 种状态

看 Timed Waiting 右侧,Timed Waiting ----> Blocked:跟 Waiting 一样,其他线程执行 notify () 和 notifyAll (),当前线程也是先进入 Blocked 状态,而后视锁的获取情况再决定是否进入 Runnable 状态。

另外,Timed Waiting ----> Runnable :1、当前线程的超时时间到了且能直接获取到锁,2、join 的线程运行结束,3、被中断,4、调用了 LockSupport.unpark (),这几种情况会直接恢复到 Runnable,而无需经历 Blocked 状态。

Terminated(被终止)

最后一种,想要进入终止状态就比较简单了,有三种情况:

  • 任务执行完毕,线程正常退出。

  • 出现一个没有捕获的异常(比如直接调用 interrupt () 方法)。

到此,关于“java线程有多少种状态”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI