Java Thread 源码解析

来源:互联网 发布:四川广电网络客服电话 编辑:程序博客网 时间:2024/06/05 23:51

Thread 源码解析

线程的方法大部分都是使用Native使用,不允许应用层修改,是CPU调度的最基本单元。线程的资源开销相对于进程的开销是相对较少的,所以我们一般创建线程执行,而不是进程执行。

Thread 构造方法

/** * Initializes a Thread. * * @param g the Thread group * @param target the object whose run() method gets called * @param name the name of the new Thread * @param stackSize the desired stack size for the new thread, or *        zero to indicate that this parameter is to be ignored. */private void init(ThreadGroup g, Runnable target, String name, long stackSize) {    Thread parent = currentThread();    if (g == null) {        g = parent.getThreadGroup();    }    g.addUnstarted();    this.group = g;    this.target = target;    this.priority = parent.getPriority();    this.daemon = parent.isDaemon();    setName(name);    init2(parent);    /* Stash the specified stack size in case the VM cares */    this.stackSize = stackSize;    tid = nextThreadID();}/** * Throws CloneNotSupportedException as a Thread can not be meaningfully * cloned. Construct a new Thread instead. * * @throws  CloneNotSupportedException *          always */@Overrideprotected Object clone() throws CloneNotSupportedException {    throw new CloneNotSupportedException();}public Thread() {    init(null, null, "Thread-" + nextThreadNum(), 0);}public Thread(Runnable target) {    init(null, target, "Thread-" + nextThreadNum(), 0);}public Thread(ThreadGroup group, Runnable target) {    init(group, target, "Thread-" + nextThreadNum(), 0);}public Thread(String name) {    init(null, null, name, 0);}public Thread(ThreadGroup group, String name) {    init(group, null, name, 0);}/** @hide */// Android added : Private constructor - used by the runtime.Thread(ThreadGroup group, String name, int priority, boolean daemon) {    this.group = group;    this.group.addUnstarted();    // Must be tolerant of threads without a name.    if (name == null) {        name = "Thread-" + nextThreadNum();    }    // NOTE: Resist the temptation to call setName() here. This constructor is only called    // by the runtime to construct peers for threads that have attached via JNI and it's    // undesirable to clobber their natively set name.    this.name = name;    this.priority = priority;    this.daemon = daemon;    init2(currentThread());    tid = nextThreadID();}private void init2(Thread parent) {    this.contextClassLoader = parent.getContextClassLoader();    this.inheritedAccessControlContext = AccessController.getContext();    if (parent.inheritableThreadLocals != null) {        this.inheritableThreadLocals = ThreadLocal.createInheritedMap(                parent.inheritableThreadLocals);    }}public Thread(Runnable target, String name) {    init(null, target, name, 0);}public Thread(ThreadGroup group, Runnable target, String name) {    init(group, target, name, 0);}public Thread(ThreadGroup group, Runnable target, String name,              long stackSize) {    init(group, target, name, stackSize);}

Thread 中构造方法好好多种,如果在构造方法中没有传入线程name,那么Thread类中是会默认的为我们规定线程名字,即调用的是Thread- nextThreadNum(),对线程进行编号。 这个方法是同步的,保证了在执行的时候不会进行异步操作,避免了产生有相同的线ID的出现。在构造方法中都执行了init()方法, init 方法是私有的,会判断ThreadGroup 是否为空。

Thread的是实现了Runnable接口的,run 方法应该是怎么执行的?

@Overridepublic void run() {    if (target != null) {        target.run();    }}

run 方法中的target 变量就是我们在初始化的时候传入的变量,如果子类复写了run 方法,就不会调用target.run()

Thread 中重要的方法:

start() 方法

/** * Causes this thread to begin execution; the Java Virtual Machine * calls the <code>run</code> method of this thread. * <p> * The result is that two threads are running concurrently: the * current thread (which returns from the call to the * <code>start</code> method) and the other thread (which executes its * <code>run</code> method). * <p> * It is never legal to start a thread more than once. * In particular, a thread may not be restarted once it has completed * execution. * * @exception  IllegalThreadStateException  if the thread was already *               started. * @see        #run() * @see        #stop() */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);    started = false;    try {        nativeCreate(this, stackSize, daemon);        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( )方法是同步的,并且是启动这个线程进行执行,Java虚拟机将会调用这个线程的run方法,这样产生的结果是,两个线程执行着,其中一个是调用start()方法的线程执行,另一个线程是执行run方法的线程。在start()方法中,首先进行的线程状态的判断,如果是一个JVM新启动的线程,那么threadStatus 的状态是为0的,如果线程不为0 将报出异常, 然后将线程添加到group中, group.add(this)方法中执行的结果是,通知group, 这个线程要执行了,所以可以添加进group中,然后调用本地方法nativeCreate(this, stackSize, daemon);

sleep() 方法

/** * Causes the currently executing thread to sleep (temporarily cease * execution) for the specified number of milliseconds plus the specified * number of nanoseconds, subject to the precision and accuracy of system * timers and schedulers. The thread does not lose ownership of any * monitors. * * @param  millis *         the length of time to sleep in milliseconds * * @param  nanos *         {@code 0-999999} additional nanoseconds to sleep * * @throws  IllegalArgumentException *          if the value of {@code millis} is negative, or the value of *          {@code nanos} is not in the range {@code 0-999999} * * @throws  InterruptedException *          if any thread has interrupted the current thread. The *          <i>interrupted status</i> of the current thread is *          cleared when this exception is thrown. */public static void sleep(long millis, int nanos)throws InterruptedException {    if (millis < 0) {        throw new IllegalArgumentException("millis < 0: " + millis);    }    if (nanos < 0) {        throw new IllegalArgumentException("nanos < 0: " + nanos);    }    if (nanos > 999999) {        throw new IllegalArgumentException("nanos > 999999: " + nanos);    }    // The JLS 3rd edition, section 17.9 says: "...sleep for zero    // time...need not have observable effects."    if (millis == 0 && nanos == 0) {        // ...but we still have to handle being interrupted.        if (Thread.interrupted()) {          throw new InterruptedException();        }        return;    }    long start = System.nanoTime();    long duration = (millis * NANOS_PER_MILLI) + nanos;    Object lock = currentThread().lock;    // Wait may return early, so loop until sleep duration passes.    synchronized (lock) {        while (true) {            sleep(lock, millis, nanos);            long now = System.nanoTime();            long elapsed = now - start;            if (elapsed >= duration) {                break;            }            duration -= elapsed;            start = now;            millis = duration / NANOS_PER_MILLI;            nanos = (int) (duration % NANOS_PER_MILLI);        }    }}

sleep()方法在使用线程的时候,用的是比较多的。 这个方法的作用使得当前线程休眠一定的时间,但是这个期间是不释放持有的锁的。这个方法里面首先进行的是休眠时间的判断,然后又是调用本地方法。

join()方法

/** * Waits at most {@code millis} milliseconds for this thread to * die. A timeout of {@code 0} means to wait forever. * * <p> This implementation uses a loop of {@code this.wait} calls * conditioned on {@code this.isAlive}. As a thread terminates the * {@code this.notifyAll} method is invoked. It is recommended that * applications not use {@code wait}, {@code notify}, or * {@code notifyAll} on {@code Thread} instances. * * @param  millis *         the time to wait in milliseconds * * @throws  IllegalArgumentException *          if the value of {@code millis} is negative * * @throws  InterruptedException *          if any thread has interrupted the current thread. The *          <i>interrupted status</i> of the current thread is *          cleared when this exception is thrown. */public final void join(long millis) throws InterruptedException {    synchronized(lock) {    long base = System.currentTimeMillis();    long now = 0;    if (millis < 0) {        throw new IllegalArgumentException("timeout value is negative");    }    if (millis == 0) {        while (isAlive()) {            lock.wait(0);        }    } else {        while (isAlive()) {            long delay = millis - now;            if (delay <= 0) {                break;            }            lock.wait(delay);            now = System.currentTimeMillis() - base;        }    }    }}

join方法是等待该线程执行,直到超时或者终止,可以作为线程通信的一种方式,A线程调用B线程的join(阻塞),等待B完成后再往下执行

interrupt()方法

public void interrupt() {    if (this != Thread.currentThread())        checkAccess();    synchronized (blockerLock) {        Interruptible b = blocker;        if (b != null) {            nativeInterrupt();            b.interrupt(this);            return;        }    }    nativeInterrupt();}

interrupt()方法是中断当前的线程,一般来说,阻塞函数:如Thread.sleep、Thread.join、Object.wait等在检查到线程的中断状态的时候,会抛出InteruptedExeption, 同时会清除线程的中断状态。

线程状态

/** * A thread state.  A thread can be in one of the following states: * <ul> * <li>{@link #NEW}<br> *     A thread that has not yet started is in this state. *     </li> * <li>{@link #RUNNABLE}<br> *     A thread executing in the Java virtual machine is in this state. *     </li> * <li>{@link #BLOCKED}<br> *     A thread that is blocked waiting for a monitor lock *     is in this state. *     </li> * <li>{@link #WAITING}<br> *     A thread that is waiting indefinitely for another thread to *     perform a particular action is in this state. *     </li> * <li>{@link #TIMED_WAITING}<br> *     A thread that is waiting for another thread to perform an action *     for up to a specified waiting time is in this state. *     </li> * <li>{@link #TERMINATED}<br> *     A thread that has exited is in this state. *     </li> * </ul> * * <p> * A thread can be in only one state at a given point in time. * These states are virtual machine states which do not reflect * any operating system thread states. * * @since   1.5 * @see #getState */public enum State {    /**     * Thread state for a thread which has not yet started.     */    NEW,    /**     * Thread state for a runnable thread.  A thread in the runnable     * state is executing in the Java virtual machine but it may     * be waiting for other resources from the operating system     * such as processor.     */    RUNNABLE,    /**     * Thread state for a thread blocked waiting for a monitor lock.     * A thread in the blocked state is waiting for a monitor lock     * to enter a synchronized block/method or     * reenter a synchronized block/method after calling     * {@link Object#wait() Object.wait}.     */    BLOCKED,    /**     * Thread state for a waiting thread.     * A thread is in the waiting state due to calling one of the     * following methods:     * <ul>     *   <li>{@link Object#wait() Object.wait} with no timeout</li>     *   <li>{@link #join() Thread.join} with no timeout</li>     *   <li>{@link LockSupport#park() LockSupport.park}</li>     * </ul>     *     * <p>A thread in the waiting state is waiting for another thread to     * perform a particular action.     *     * For example, a thread that has called <tt>Object.wait()</tt>     * on an object is waiting for another thread to call     * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on     * that object. A thread that has called <tt>Thread.join()</tt>     * is waiting for a specified thread to terminate.     */    WAITING,    /**     * Thread state for a waiting thread with a specified waiting time.     * A thread is in the timed waiting state due to calling one of     * the following methods with a specified positive waiting time:     * <ul>     *   <li>{@link #sleep Thread.sleep}</li>     *   <li>{@link Object#wait(long) Object.wait} with timeout</li>     *   <li>{@link #join(long) Thread.join} with timeout</li>     *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>     *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>     * </ul>     */    TIMED_WAITING,    /**     * Thread state for a terminated thread.     * The thread has completed execution.     */    TERMINATED;}

1、NEW

新建立的线程,还没有调用start()方法

2、 RUNNABLE
可以运行,需要再等到其他资源(如CPU)就绪才能运行
3、 BLOCKED
线程调用wait()后等待内置锁进入同步方法或块中

4、WAITING
在调用无参的wait(),Thread.join()

5、TIMED_WAITING
调用Thread.sleep(), 有时间参数的wait(), 有时间参数的Thread.join()
6、TERMINATED
执行完毕的线程状态

0 0
原创粉丝点击