Java线程状态

1、Java定义了 6种线程状态

 NEW 新生状态  new Thread() 线程即进入新生状态

 RUNNABLE 可运行状态   t.start() 调用该方法后进入可运行状态(可运行说明可能正在执行也可能在等待或阻塞)

 BLOCKED 阻塞状态:线程试图获得synchronized同步锁的这段时间内,处于阻塞状态

 WAITING 等待状态:调用对象的 wait或者sleep 方法,将使当前线程进入等待状态

 TIMED_WAITING 计时等他:调用wait(time)和sleep(time)都将进入计时等待

 TERMINATED 被终止:线程正常执行完或者由于异常退出,都进入该状态


可能比较难区分的就是阻塞和等待这两种状态,按照Java对这两种状态的定义

其实也不难理解:blocking 阻塞,是线程试图进入被 synchronized 同步块时,当前线程要获得锁才能进入同步块

但这一刻可能锁被其他线程持有了,那当前线程其实就进入了 阻塞 状态

特别注意:线程调用 start 方法,就进入了 runnable可运行状态,进入同步块和进入 run 方法是完全不同的两个概念

只要 run 方法没有被 synchronized 修饰,那么所有线程在start 之后都能顺利进入 run 方法体

只是要进入 run 方法里面的同步块时,如果获取锁失败,才会进入阻塞!


2、演示线程的全状态

package com.test.concurrent.state;

import java.lang.Thread.State;

/**
 * 演示线程的各种状态,并解释每个阶段的状态是如何转换的!
 * 特别解释了  阻塞 和 等待 这两种状态的区别
 * 也延伸出来 sleep 和  wait 最核心的区别
 * sleep 不会释放当前持有的锁,但wait会释放
 * 
 * @author yli
 */
public class ThreadStateTest {

    // 定义一个对象,用来控制同步锁
    public static Integer num = 0;

    public static void main(String[] args) throws InterruptedException {
        // Java定义了 6种线程状态
        // NEW 新生状态  new Thread() 线程即进入新生状态
        // RUNNABLE 可运行状态   t.start() 调用该方法后进入可运行状态(可运行说明很可能处于阻塞或者等待状态,不一定在运行)
        // BLOCKED 阻塞状态:当线程获得synchronized同步锁的这段时间内,处于阻塞状态
        // WAITING 等待状态:调用对象的 wait或者sleep 方法,将使当前线程进入等待状态
        // TIMED_WAITING 计时等他:调用wait(time)和sleep(time)都将进入计时等待
        // TERMINATED 被终止:线程正常执行完或者由于异常退出,都进入该状态
        State[] states = Thread.State.values();
        for (State s : states) {
            System.out.println(s.toString());
        }

        System.out.println("*************************\n\n");

        // NEW 新生状态
        Thread t1 = new Thread(new ThreadState(), "t1");
        Thread t2 = new Thread(new ThreadState(), "t2");
        
        System.out.println("线程对象被创建,t1 线程状态:" + t1.getState());
        System.out.println("线程对象被创建,t2 线程状态:" + t2.getState());
        System.out.println("\n\n");

        // 启动 t1 线程,main主线程休眠100毫秒,让t1运行起来
        t1.start();
        Thread.sleep(100);
        // 100ms这段时间内 t1 会进入运行状态,并且进入同步块之后,线程会休眠2s
        // 打印此时线程的状态:应该是 TIMED_WAITING 计时等待状态
        System.out.println("t1的线程状态:" + t1.getState());
        System.out.println("\n\n");

        // 接下来启动t2线程,因为同一时刻只能有一个线程进入同步块(即只有一个线程可以获得锁)
        // 由于 t1 获得锁之后,会休眠2s:休眠不会释放锁!!!这导致 t2 会被阻塞!!!
        // 所以 t2 一开始能运行,进入run方法体,但尝试进入同步块,会阻塞
        t2.start();
        Thread.sleep(100); // 同样的主线程休眠100毫秒,让t2运行起来
        System.out.println("t2的线程状态:" + t2.getState());
        System.out.println("\n\n");
        
        
        // 2s后,t1 休眠已结束,但马上调用了wait方法进入等待,再来看看 t1 此时的状态
        Thread.sleep(2000);
        System.out.println("t1的线程状态:" + t1.getState());
        
        
        // t2 其实就比t1晚启动100毫秒,但t2启动后又让主线程休眠了100毫秒
        // 所以再等2秒,t1和t2的sleep肯定都已经结束,都进入了wait计时等待
        // 这里演示:使用 notifyAll 通知t1 和 t2 可以不再等待了
        synchronized (ThreadStateTest.num) {
            ThreadStateTest.num.notifyAll();
        }
        
        // 等t1 和 t2 全部运行完,来看看他们的状态
        t1.join();
        System.out.println("t1的线程状态:" + t1.getState());
        
        t2.join();
        System.out.println("t2的线程状态:" + t2.getState());
    }
}

class ThreadState implements Runnable {

    @Override
    public void run() {
        String tname = "线程:" + Thread.currentThread().getName();
        System.out.println(tname + " 进入run方法块,线程状态:" + Thread.currentThread().getState());
        
        synchronized (ThreadStateTest.num) {
            System.out.println(tname + " 获得锁,进入同步块,线程状态:" + Thread.currentThread().getState());
            try {
                System.out.println(tname + " 进入sleep");
                Thread.sleep(2000);
                
                System.out.println(tname + " 进入wait");
                
                ThreadStateTest.num.wait();
                
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

    }

}

打印结果如下

NEW
RUNNABLE
BLOCKED
WAITING
TIMED_WAITING
TERMINATED
*************************


线程对象被创建,t1 线程状态:NEW
线程对象被创建,t2 线程状态:NEW


线程:t1 进入run方法块,线程状态:RUNNABLE
线程:t1 获得锁,进入同步块,线程状态:RUNNABLE
线程:t1 进入sleep
t1的线程状态:TIMED_WAITING


线程:t2 进入run方法块,线程状态:RUNNABLE
t2的线程状态:BLOCKED


线程:t1 进入wait
线程:t2 获得锁,进入同步块,线程状态:RUNNABLE
线程:t2 进入sleep
t1的线程状态:WAITING
线程:t2 进入wait
t1的线程状态:TERMINATED
t2的线程状态:TERMINATED


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值