java线程状态

一、java线程的6种状态

Java线程在其生命周期中会经历不同的状态,Java语言在Thread.State枚举中明确定义了6种线程状态:

1、NEW(新建状态)

2、RUNNABLE(可运行状态)

3、TIMED_WAITING(计时等待状态)

4、BLOCKED(阻塞状态)

5、WAITING(等待状态)

6、TERMINATED(终止状态)

二、各状态详解及转换条件

1、NEW(新建状态)

含义:线程被创建但尚未启动时的状态。此时线程对象已存在,但还没有调用start()方法。 

Thread t=new Thread();
System.out.println(t.getState());

 2、RUNNABLE(可运行状态)

含义:可工作的,又分为正在工作和随时准备工作

NEW → RUNNABLE转换条件:调用线程的start()方法

Thread t=new Thread();//此时线程处于NEW状态
t.start();//转换为RUNNABLE状态
System.out.println(t.getState());

3、TIMED_WAITING(限时等待状态)

含义:线程在指定时间内等待,超时后自动返回,无需显示唤醒。

RUNNABLE→ TIMED_WAITING进入方式:

(1)Thread.sleep(long)

(2)Object.wait(long)

(3)Thread.join(long)

(4)LockSupport.parkNanos()

(5)LockSupport.parkUntil()

TIMED_WAITING→ RUNNABLE:等待时间结束或被唤醒

举个例子:

Thread t=new Thread(()->{
    try{
        System.out.println("线程状态: " + Thread.currentThread().getState()); // RUNNABLE
        Thread.sleep(2000); // 进入TIMED_WAITING
        System.out.println("当前状态: " + Thread.currentThread().getState()); // RUNNABLE
    }catch(InterruptedException e){
        e.printStackTrace();
    }
});
t.start();
while(t.getState() != Thread.State.TERMINATED){
    Thread.sleep(1000);
    System.out.println("当前状态: " + t.getState());
}

代码运行结果如下:

从这个结果我们可以看出带有时间参数的sleep方法可以让线程进入 TIMED_WAITING状态,同样的join(时间)等方法也能进入TIMED_WAITING状态

4、 BLOCKED(阻塞状态) 

含义:线程因为等待获取一个排它锁而被阻塞的状态。(通俗来说,就是t1线程持有锁,t2线程现在要尝试获取这个锁,如果无法获取就进入BLOCKED状态)

 RUNNABLE→BLOCKED进入方式:

等待进入synchronized方法/块

synchronized(lock) {  // 如果其他线程持有lock,当前线程会进入BLOCKED状态
    // 获取到锁后进入RUNNABLE状态
}

 BLOCKED → RUNNABLE:成功获取到所需的锁

特点:

必须有两个以上线程竞争同一把锁才会出现

不消耗CPU资源

不可中断

接下来我们来看一段完整的代码理解这个阻塞过程

    private static final Object lock = new Object(); // 共享锁对象
    public static void main(String[] args) throws InterruptedException {
        // 线程1 - 持有锁3秒
        Thread t1 = new Thread(() -> {
            synchronized (lock) {
                System.out.println("线程1获取锁,状态: " + Thread.currentThread().getState());
                try {
                    Thread.sleep(3000); // TIMED_WAITING
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        // 线程2 - 尝试获取锁
        Thread t2 = new Thread(() -> {
            System.out.println("线程2尝试获取锁...");
            synchronized (lock) { // 这里会BLOCKED
                System.out.println("线程2获取锁成功");
            }
        });
        t1.start();
        Thread.sleep(100); // 确保t1先获取锁
        t2.start();
        // 监控t2状态
        while(true) {
            System.out.println("线程2状态: " + t2.getState());
            if(t2.getState() == Thread.State.TERMINATED) break;
            Thread.sleep(500);
        }
    }

代码运行结果如下:

 

我们将 BLOCKED与TIMED_WAITING进行比对

TIMED_WAITING:由sleep()、wait(timeout)等方法引起,是主动等待

BLOCKED:由锁竞争引起,是被动阻塞

5、WAITING(无限期等待状态)

含义:线程无限期等待其他线程执行特定操作,需要被显式唤醒。

RUNNABLE→ TIMED_WAITING进入方式:

调用Object.wait()

调用Thread.join()

调用LockSupport.park() 

synchronized(lock) {
    lock.wait();  // 进入WAITING状态
}

WAITING → RUNNABLE:被其他线程唤醒(notify()/notifyAll()或目标线程终止)

synchronized(lock) {
    lock.notify();  // 唤醒等待线程
}

我们来看一段完整的过程

private static final Object lock = new Object(); // 共享锁对象
public static void main(String[] args) throws InterruptedException {
    Thread t=new Thread(()->{
        synchronized (lock){
            try {
                System.out.println("线程状态: " + Thread.currentThread().getState()); // RUNNABLE
                lock.wait(); // 释放锁并进入WAITING状态
                System.out.println("当前状态: " + Thread.currentThread().getState()); // RUNNABLE
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            }
    });
    t.start();
    //状态监控循环
    while(true){
        System.out.println("当前状态:"+t.getState());
        if(t.getState() == Thread.State.WAITING){
            synchronized (lock) {//获取同一把锁
                System.out.println("[主线程] 检测到WAITING状态,准备唤醒...");
                lock.notify();//唤醒等待线程
                System.out.println("[主线程] 已发送唤醒通知");
            }
        }
        if (t.getState() == Thread.State.TERMINATED) {
            break;//终止线程循环
        }
        Thread.sleep(300); // 监控间隔
    }
}    

代码的运行结果如下:

 

6、TERMINATED(终止状态)

含义:线程执行完毕(run()方法正常结束)或因异常退出后的状态。 

进入TERMINATED状态

(1)、正常完成执行

new Thread(() -> {
    System.out.println("执行任务...");
    // run()方法自然结束
}).start();

(1)、抛出未捕获的异常

new Thread(() -> {
    throw new RuntimeException("意外错误");
}).start();

注意: 

  • 一旦进入TERMINATED状态,线程就不能再次启动,具有不可逆性;

  • 线程栈等资源会被JVM回收,但Thread对象本身仍然存在;

  • 可通过getState()方法检测,isAlive()方法返回false

TERMINATED状态与其他状态的关系 

NEW → RUNNABLE → (BLOCKED/WAITING/TIMED_WAITING) → RUNNABLE → TERMINATED

下面我们来看一段完整的过程:

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            System.out.println("线程开始执行...");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t.start();
        // 监控线程状态变化
        while (t.getState() != Thread.State.TERMINATED) {
            System.out.println("运行中状态: " + t.getState());
            Thread.sleep(300);
        }
        System.out.println("最终状态: " + t.getState()); // TERMINATED
        // 尝试重新启动
        try {
            t.start(); // 抛出IllegalThreadStateException
        } catch (IllegalThreadStateException e) {
            System.out.println("不能重新启动已终止的线程");
        }
    }

代码运行结果如下:

三、总结

状态变化简易图

      实例化
       │
       ▼
     NEW (新建) 
       │
       │ Thread.start()
       ▼
   ┌─────────────┐
   │ RUNNABLE    │◄──────────────────────┐
   │ (可运行)     │                       │
   ├─────┬───────┤                       │
   │READY│RUNNING│                       │
   └─────┴───────┘                       │
       │    │                            │
       │    │ 竞争锁失败                  │
       │    ▼                            │
       │ BLOCKED (阻塞)                   │
       │    │                            │
       │    │ 获取到锁                    │
       │    ▼                            │
       │ wait()/join()/park()          notify()/unpark()
       ▼    │                            │
   WAITING (无限等待)                     │
       │    │                            │
       │    │ sleep(timeout)/wait(timeout)│
       ▼    ▼                            │
 TIMED_WAITING (超时等待)                 │
       │    │                            │
       │    │ 超时/被唤醒                  │
       └────┴────────────────────────────┘
               │
               │ 执行完成
               ▼
           TERMINATED (终止)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值