线程的生命周期

1.线程的状态

public class Thread implements Runnable {
     
	public enum State {
     
        NEW,

        RUNNABLE,
        
        BLOCKED,

        WAITING,
        
        TIMED_WAITING,
        
        TERMINATED;
    }
    
	public State getState() {
     
		//获取当前线程状态
        return sun.misc.VM.toThreadState(threadStatus);
    }
}

如线程源码所示,共定义了6种线程状态,NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING以及TERMINATED。

2.线程状态转换
线程6个状态之间的转换如下图所示。
线程的生命周期_第1张图片

  • NEW(初始):实现Runnable接口和继承Thread可以得到一个线程类,new一个实例获得一个线程对象,但未调用start()方法,此时线程就进入了初始状态。
  • RUNNABLE(运行):Java线程中将READY(就绪)和RUNNING(运行中)两种状态合称为运行状态。线程对象创建后,其他线程如main线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态。就绪状态的线程在获得CPU时间片后变为运行中状态。
  • BLOCKED(阻塞):阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态。
  • WAITING(等待):处于该状态的线程不会被分配CPU执行时间,它们需要等待被显式地唤醒,否则会处于无限期等待的状态。
  • TIMED_WAITING(超时等待):处于该状态的线程不会被分配CPU执行时间,不过无须无限期等待被其他线程显示地唤醒,在达到一定时间后它们会自动唤醒。
  • TERMINATED():该线程已经执行完毕或遇到没有捕获的异常。

3.NEW、RUNNABLE以及TERMINATED状态的代码演示

public class NewRunnableTerminated implements Runnable {
     
    @Override
    public void run() {
     
        for (int i = 1; i <= 1000; i++) {
     
            System.out.println("正在输出" + i);
        }
    }

    public static void main(String[] args) {
     
        Thread thread = new Thread(new NewRunnableTerminated());
        System.out.println("当前线程状态:" + thread.getState());
        thread.start();
        System.out.println("当前线程状态:" + thread.getState());
        try {
     
            //休眠10ms的作用是使得子线程在执行过程中可以打印线程状态
            Thread.sleep(2);
        } catch (InterruptedException e) {
     
            e.printStackTrace();
        }
        System.out.println("当前线程状态:" + thread.getState());
        try {
     
            Thread.sleep(100);
        } catch (InterruptedException e) {
     
            e.printStackTrace();
        }
        System.out.println("当前线程状态:" + thread.getState());
    }
}

程序执行结果如下所示,在线程创建和调用start()方法后子线程运行前,线程状态分别为NEW和RUNNABLE,然后执行子线程任务,在执行过程中打印线程状态依然为RUNNABLE,最后线程执行完毕后,线程状态为TERMINATED。值得注意的是,如果在线程执行完毕后,再次调用start()方法时,会抛java.lang.IllegalThreadStateException异常。

当前线程状态:NEW
当前线程状态:RUNNABLE
正在输出1
正在输出2
正在输出3
......
当前线程状态:RUNNABLE
......
正在输出998
正在输出999
正在输出1000
当前线程状态:TERMINATED

4.BLOCKED、WAITING以及TIMED_WAITING状态的代码演示

public class BlockedWaitingTimedWaiting implements Runnable {
     

    public static void main(String[] args) {
     
        BlockedWaitingTimedWaiting blockedWaitingTimedWaiting = new BlockedWaitingTimedWaiting();
        Thread t1 = new Thread(blockedWaitingTimedWaiting);
        t1.start();

        Thread t2 = new Thread(blockedWaitingTimedWaiting);
        t2.start();
        try {
     
            Thread.sleep(5);
        } catch (InterruptedException e) {
     
            e.printStackTrace();
        }
        System.out.println("线程1当前状态:" + t1.getState());
        System.out.println("线程2当前状态:" + t2.getState());
        try {
     
            //这里必须大于1000ms的作用是让线程1执行完sleep方法后执行wait方法
            Thread.sleep(1300);
        } catch (InterruptedException e) {
     
            e.printStackTrace();
        }
        System.out.println("线程1当前状态:" + t1.getState());
    }

    @Override
    public void run() {
     
        syn();
    }

    private synchronized void syn() {
     
        try {
     
            Thread.sleep(1000);
            wait();
        } catch (InterruptedException e) {
     
            e.printStackTrace();
        }
    }
}

程序执行结果如下所示。

线程1当前状态:TIMED_WAITING
线程2当前状态:BLOCKED
线程1当前状态:WAITING

你可能感兴趣的:(从头开始学Java高并发)