Java并发-5.线程状态

Java线程有6种状态

Java线程在运行的声明周期有6中不同的状态,给任一时刻,线程只能处于其中一种状态:

状态

说明

NEW

初始状态,线程被构建的,但是还没有调用start()方法

RUNNABLE

运行状态,这里包括操作系统中的就绪和运行两种状态,Java统称“运行中”

BLOCKED

阻塞,标识线程阻塞于锁

WAITING

等待,标识当前线程需要等待其他线程作出一些特定操作(通知或中断)

TIME_WAITING

超时等待,不同于WAITING,可在指定时间后自行返回

TERMINATED

中止,标识线程已经执行完毕

示例代码: ThreadState

/**
 * Java线程的各种状态
 *
 * @author pengjunzhe
 */
public class ThreadState {

    public static void main(String[] args) {
        new Thread(new TimeWaiting(), "TimeWaitingThread").start();
        new Thread(new Waiting(), "WaitingThread").start();
        new Thread(new Blocked(), "BlockedThread-1").start();
        new Thread(new Blocked(), "BlockedThread-2").start();
    }

    /**
     * 该线程不断进行睡眠
     */
    static class TimeWaiting implements Runnable {
        @Override
        public void run() {
            while (true) {
                SleepUtils.second(100);
            }
        }
    }

    /**
     * 该线程在Waiting.class实例上等待
     */
    static class Waiting implements Runnable {
        @Override
        public void run() {
            while (true) {
                synchronized (Waiting.class) {
                    try {
                        Waiting.class.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 阻塞的线程,在Blocked.class实例上加锁后,不会释放锁
     */
    static class Blocked implements Runnable {
        @Override
        public void run() {
            synchronized (Blocked.class) {
                while (true) {
                    SleepUtils.second(100);
                }
            }
        }
    }
}

SleepUtils

import java.util.concurrent.TimeUnit;

public class SleepUtils {
    public static final void second(long seconds) {
        try {
            TimeUnit.SECONDS.sleep(seconds);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

查看线程pid:

$jps
48316 ThreadState
48317 Jps

查看线程状态:

$jstack 48316
"TimeWaitingThread" #13 prio=5 os_prio=31 tid=0x00007fe47383b000 nid=0xa703 waiting on condition [0x000070000928f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at java.lang.Thread.sleep(Thread.java:340)
        at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
        at com.junzerg.threads.SleepUtils.second(SleepUtils.java:8)
        at com.junzerg.threads.ThreadState$TimeWaiting.run(ThreadState.java:24)
        at java.lang.Thread.run(Thread.java:748)
"WaitingThread" #14 prio=5 os_prio=31 tid=0x00007fe47481b000 nid=0x5903 in Object.wait() [0x0000700009392000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x000000076ae4b270> (a java.lang.Class for com.junzerg.threads.ThreadState$Waiting)
        at java.lang.Object.wait(Object.java:502)
        at com.junzerg.threads.ThreadState$Waiting.run(ThreadState.java:38)
        - locked <0x000000076ae4b270> (a java.lang.Class for com.junzerg.threads.ThreadState$Waiting)
        at java.lang.Thread.run(Thread.java:748)
"BlockedThread-1" #15 prio=5 os_prio=31 tid=0x00007fe470853800 nid=0xa403 waiting on condition [0x0000700009495000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at java.lang.Thread.sleep(Thread.java:340)
        at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
        at com.junzerg.threads.SleepUtils.second(SleepUtils.java:8)
        at com.junzerg.threads.ThreadState$Blocked.run(ThreadState.java:55)
        - locked <0x000000076ae4f498> (a java.lang.Class for com.junzerg.threads.ThreadState$Blocked)
        at java.lang.Thread.run(Thread.java:748)

Java线程状态之间的变化

  • 线程实例化之后进入初始状态(NEW)
  • 调用Thread.start()方法后进入运行状态(RUNNABLE)
    • 操作系统调度线程在就绪(READY)和运行中(RUNNING)状态中切换
    • JVM能用yield()方法使进程从运行中切换到就绪,其他不能干涉
  • 线程可以在RUNNABLE和WAITING间切换:
    • 以下方法可以使进程从RUNNABLE切换到WAITING:
      • Object.wait()
      • Object.join()
      • LockSupper.park()
    • 以下方法使进程从WAITING切换到RUNNABLE:
      • Object.notify()
      • Object.notifyAll()
      • LockSupper.unpark(Thread)
  • 线程可以在RUNNABLE和TIMED_WAITING间切换:
    • 以下方法使进程从RUNNABLE切换到TIMED_WAITING:
      • Thread.sleep(long)
      • Object.wait(long)
      • Object.join(long)
      • LockSupper.parkNanos()
      • LockSupper.parkUntil()
    • 以下方法使线程从TIME_WAITING切换到到RUNNABLE:
      • Object.notify()
      • Object.notifyAll()
      • LockSupper.unpark(Thread)
      • 超时时间到
  • 线程可以在RUNNABLE和BLOCKED中切换
    • 以下方法线程从RUNNABLE切换到BLOCKED:
      • 等待进入synchronize方法
      • 等待进入synchronize块
    • 以下方法线程从阻塞切换到RUNNABLE:
      • 获取到锁
  • 线程执行完成后进入中止状态(TERMINATED)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏银河系资讯

Python列表推导(list comprehension)VS 生成器表达式(generator expression

列表是一种可以表示为元素集合的数据。一个简单的列表如下所示:[0, 1, 2, 3, 4, 5] 列表将所有可能类型的数据和数据组合作为其元素:

13210
来自专栏Java那些事

想进大厂光靠背面试题可没用,谈谈如何真正掌握一个技术知识点

如何真正地掌握一个技术知识点,这是我一直在探索的一个问题,在秋招复习的那段时间,我主要通过阅读博客、整理博客等方式构建了自己的知识体系,所以也算是有了一些经验,...

13430
来自专栏Web技术布道师

如何快速掌握HTTP协议(高清思维导图 )

HTTP 协议极其庞杂,它影响着浏览器、爬虫、代理服务器、防火墙、CDN、Web 容器、微服务等诸多方面,自身的规范却并不统一,所要面对的各类软件的新旧版本也同...

24030
来自专栏程序员果果

Spring Boot 整合 rabbitmq

场景:用户注册,信息写入数据库后,需要给用户发送注册成功的邮件,再发送注册成功的邮件。

13230
来自专栏京程一灯

Chrome 74 带来的新功能[每日前端夜话0x66]

Chrome 74 已经发布了,虽然从用户的角度来看并没有什么令人兴奋的东西,但是对开发人员来说带来了一些好处。新版本附带了新的 Javascript 私有类字...

13320
来自专栏腾讯Bugly的专栏

Android app反调试与代码保护的一些基本方案

| 导语 本文介绍Android app代码(java + ndk)的反调试的方法和保护代码增加逆向难度的一些基本方法。 Android自问世以来得以迅速发展...

61040
来自专栏银河系资讯

Java创建Annotation

注解是Java很强大的部分,但大多数时候我们倾向于使用而不是去创建注解。例如,在Java源代码里不难找到Java编译器处理的@Override注解,Spring...

16320
来自专栏Python数据科学

优雅你的Python代码的15个tips

前言:师妹前段时间非常认真地选了下学期的《大数据分析实践》选修课,根据几位师兄的建议买了本书开始自学 Python 语言。然而年后再见,师妹说她看完了书,做了一...

9820
来自专栏芋道源码1024

4 个关于Java 虚拟机内存的问题?

JVM的内存划分中,有部分区域是线程私有的,有部分是属于整个JVM进程;有些区域会抛出OOM异常,有些则不会,了解JVM的内存区域划分以及特征,是定位线上内存问...

10010
来自专栏一名叫大蕉的程序员

承认吧你压根不懂怎么学新语言 No.142

我相信所有的人基本都会有刚开始入门学习某门语言的时候,比如 Python、JS、Java、Go、Scala,所有人一开始都会被 Hello World !吸引,...

9310

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励