Java中线程有哪些状态?分别表示什么含义?

188 阅读3分钟

1.线程的状态

1.1 线程状态的种类

  线程状态是指描述线程在不同阶段的状态或情况。在Java中,线程的状态有 6 种,我们通过下面的代码来看看这6种状态。

image.png   StateThread中的一个枚举类型,这个枚举中装的就是那 6 种状态。

image.png

  那么,这 6 种状态分别表示什么含义呢?

1.2 线程各种状态的含义

  1. NEW: 新创建了一个线程对象,但还没有调用start()方法。
  2. RUNNABLE: Java线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于就绪队列中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running)。
  3. BLOCKED: 表示线程阻塞于锁。当一个线程试图获取一个对象锁,而该对象锁被其他线程持有,则当前线程进入阻塞状态。当持有锁的线程释放锁时,阻塞状态的线程将有机会获取该锁,并进入就绪状态。
  4. WAITING: 进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。例如,通过调用Object.wait()方法,使当前线程放弃对象锁并进入等待队列。或者,调用Thread.join()方法,等待指定的线程终止。
  5. TIMED_WAITING: 该状态不同于WAITING,它表示在指定的时间后自行返回。例如,通过调用sleep(long millis)方法,在**指定的时间内让当前线程暂停执行并进入超时等待状态。**调用Object.wait(long timeout)方法或join(long millis)方法,在指定的时间内让当前线程放弃对象锁或暂停执行,并进入超时等待状态。
  6. TERMINATED: 表示该线程已经执行完毕。当线程的run()方法完成时,或者主线程的main()方法完成时,或者调用stop()方法强制终止线程时,该线程就处于终止状态。

线程的状态.drawio.png

1.3 线程状态的演示

1.3.1 NEW、RUNNABLE、TERMINATED 状态转换

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

        //线程1
        Thread thread = new Thread(){
            @Override
            public void run(){
                for (int i = 0; i < 1000000; i++) {
                    //......
                }
            }
        };

        //启动线程之前的状态
        System.out.println(thread.getState());
        //启动
        thread.start();
        //启动之后的状态
        System.out.println(thread.getState());
        //等待线程1执行完成
        thread.join();
        //线程1执行完成后的状态
        System.out.println(thread.getState());
    }

结果:

image.png

1.3.2 TIMED_WAITING、WAITING

(1)TIMED_WAITING

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

        //线程1
        Thread thread = new Thread(){
            public void run(){
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        };

        thread.start();//启动线程
        Thread.sleep(1000);//确保 线程1 能执行到sleep
        System.out.println(thread.getState());
    }

结果:

image.png

(2)WAITING

    public static void main(String[] args) throws InterruptedException {
        Object object = new Object();
        Thread thread = new Thread(){
            public void run(){
                //对 object 加锁
                synchronized (object){
                    try {
                        object.wait();//wait方法,使当前执行代码的线程进行等待. (把线程放到等待队列中) 释放当前的锁。
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };

        thread.start();//开启线程
        Thread.sleep(1000);//确保线程1能执行到wait()方法
        System.out.println("线程1此时的状态:"+thread.getState());
    }

结果:

image.png

(3)BLOCKED

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

        Object object = new Object();
        Thread thread1 = new Thread(){
            public void run(){
                synchronized(object){
                    System.out.println("线程1获取锁");
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println("线程1释放锁");
                }
            }
        };
        thread1.start();

        Thread thread2 = new Thread(){
            public void run(){
                synchronized(object){
                    System.out.println("线程2获取锁");
                }
                System.out.println("线程2释放锁");
            }
        };
        thread2.start();


        //看线程2的状态
        Thread.sleep(1000);
        System.out.println("线程2此时的状态:" + thread2.getState());
    }

结果:

image.png

  对于synchronizedwait()/notify()的更详细的内容,后面再持续更新,本篇只是罗列出Java中线程的6种状态。