天天看点

回顾Java多线程编程——线程生命周期

一 概述

Java内置了对多线程编程的支持,使得可以通过充分利用cpu来开发出高效率的程序。一条线程是指进程中一个单一顺序的控制流,一个进程可以并发使用多个线程,每条线程则并行执行各自的任务。

二 回顾进程

一个进程包括由操作系统分配的内存空间,含有一个或多个线程,一个线程必须是某个进程的一部分而无法独立存在,而进程会一直运行,直到所有的非守护线程都与运行结束才能结束。

三 一个线程的生命周期

回顾Java多线程编程——线程生命周期

线程新建状态:使用java中的new关键字和Thread类或者其子类实例化出一个线程对象后,该线程对象会处于新建状态,并且保持这个状态直到调用线程的start()方法

public class Thread implements Runnable { public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }
}
           

就绪状态:当线程对象调用了start()方法之后,该线程就进入了就绪状态,就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。

运行状态:如果就绪状态的线程获取CPU资源,就可以执行run()方法,此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态,就绪状态和死亡状态。

/* What will be run. */
    private Runnable target;
    
    //Thread重写了Runnable中的run方法
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }
           

阻塞状态:如果一个线程执行了sleep(睡眠),suspend(挂起)等方法,释放当前所占用的资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或者获得设备资源之后可以重新进入就绪状态。

public static native void sleep(long millis) throws InterruptedException;

    public static void sleep(long millis, int nanos)
    throws InterruptedException {
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
            millis++;
        }

        sleep(millis);
    }
           
//Java1.8中该方法提示弃用
    @Deprecated
    public final void suspend() {
        checkAccess();
        suspend0();
    }
           

阻塞状态的几种情况:

等待阻塞:运行状态中的线程运行wait()方法时,是的该线程进入等待阻塞状态。

[Object类中]
   public final native void wait(long timeout) throws InterruptedException;

   public final void wait(long timeout, int nanos) throws InterruptedException {
        if (timeout < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos > 0) {
            timeout++;
        }

        wait(timeout);
    }

    public final void wait() throws InterruptedException {
        wait(0);
    }
           

同步阻塞:线程由于同步锁被其它线程占用在获取synchronized同步锁失败。

其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。

       死亡状态:   一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。

继续阅读