Thread源码

       忘记在哪看到的,说线程是代码执行的序列,像线一样 代码一句一句执行起来。

       最近看java Thread源码,发现些有意思的地方。

       1 sleep(long millis, int nanos) 方法,原来nanos不管用,只能精确到毫秒。

    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);
    }

 
2 run方法是怎么被调用的?

    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 || this != me)
            throw new IllegalThreadStateException();
        group.add(this);
        start0();
        if (stopBeforeStart) {
	    stop0(throwableFromStop);
	}
    }

    private native void start0();

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


这是Thread类的run()方法的代码。一目了然如果target存在的话执行target的run()方法,否则什么也不做。这样我们可以推测(因为Thread 实际运行的方法start0 是native方法 我们看不到它的实现)也就是说Thread的run()方法总是先被调用的,然后调用taget(构造函数中的Runnable对象)的run()方法。

3 join方法,使用wait实现

 

    public final synchronized void join(long millis) 
    throws InterruptedException {
	long base = System.currentTimeMillis();
	long now = 0;

	if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
	}

	if (millis == 0) {
	    while (isAlive()) {
		wait(0);
	    }
	} else {
	    while (isAlive()) {
		long delay = millis - now;
		if (delay <= 0) {
		    break;
		}
		wait(delay);
		now = System.currentTimeMillis() - base;
	    }
	}
    }


测试代码,用notify唤醒源码里的wait方法

public class JoinDemo {
	static volatile boolean flag = false;

	public static void main(String[] args) {
		final SubClass thread = new SubClass();
		thread.setName("subclass");
		thread.start();

		new Thread() {
			public void run() {
				try {
					Thread.sleep(10000);
				} catch (InterruptedException e) {

					e.printStackTrace();
				}
				synchronized (thread) {
					flag = true;
					thread.notify();  // 唤醒线程的wait方法,但是isAlive返回true,继续wait
				}
			}
		}.start();

		try {
			thread.join();
//			synchronized (thread) {
//				while (flag == false)
//					thread.wait(); // 
//			}
			System.out.println("end");

		} catch (InterruptedException e) {
			System.out.println(" join intertupted");
			e.printStackTrace();
		}

	}
}

class SubClass extends Thread {
	public void run() {
		try {
			Thread.sleep(15000);   // 15秒后,线程run方法执行结束,线程DEAD状态,isAlive()返回false
		} catch (InterruptedException e) {
			System.out.println("intertupted");
			e.printStackTrace();
		}
		
		System.out.println(" sub class end");
	}

}

值得注意的地方是,线程对象在wait,但是Thread.run()方法里面的逻辑还在执行,看上去一个线程即在wait又在running~ 很诡异是吧,再测试下,在run方法里调用wait(mills)方法。

public class JoinDemo {
	static volatile boolean flag = false;

	public static void main(String[] args) {
		final SubClass thread = new SubClass();
		thread.setName("subclass");
		thread.start();

		new Thread() {
			public void run() {
				try {
					Thread.sleep(20000);
				} catch (InterruptedException e) {

					e.printStackTrace();
				}
				synchronized (thread) {
					flag = true;
					thread.notifyAll();
				}
			}
		}.start();

		try {
			thread.join();	// main主线程,调用了thread的监控器的wait
//			synchronized (thread) {
//				while (flag == false)
//					thread.wait(); // 
//			}
			System.out.println("main end");

		} catch (InterruptedException e) {
			System.out.println(" join intertupted");
			e.printStackTrace();
		}

	}
}

class SubClass extends Thread {
	int i = 0;
	public void run() {
		try {
			while (i < 5) {
				synchronized(this){
					this.wait(5000L);
				}
				System.out.println(i++);
			}
			// Thread.sleep(15000);
		} catch (InterruptedException e) {
			System.out.println("intertupted");
			e.printStackTrace();
		}
		
		System.out.println(" sub class end");
	}
}



Thread源码_第1张图片

          每个java对象(Object的实例)都有一个等待集(wait set), 调用个对象上执行wait的线程(指令执行运行序列),调用obj.wait()方法,就把自己(线程运行序列,VM内部不是用Thread来表示的吧!!!)加入到等待集,等到notify方法被调用的时候,即obj.notify()或者obj.notifyAll(),notify唤醒等待集中的随机一个wait线程,notifyAll唤醒等待集中的所有线程,被唤醒的线程继续从阻塞的wait方法返回,继续执行代码,判断while里的条件。

     *     synchronized (obj) {
     *         while (<condition does not hold>)
     *             obj.wait(timeout);
     *         ... // Perform action appropriate to condition
     *     }

          为什么java要把wait、notify、notifyAll这些线程间同步的方法设计在根类Object里,而不是放在和Thread相关的类里。可能是因为还是那句话,线程是指令执行的序列,java是纯面向对象语言,指令执行序列上的节点就是面向过程的语言是过程,在面向对象语言中,每个对象的方法构成执行序列,同步可能发生在执行序列的任何地方(对象的方法),所以在Object中实现了同步的方法。另外使用并发包里的Mutex、信号量、Lock这些对象也可实现线程间同步互斥。

4 interrupt、interrupted、isInterrupted区别

    public void interrupt() {
	if (this != Thread.currentThread())
	    checkAccess();

	synchronized (blockerLock) {
	    Interruptible b = blocker;
	    if (b != null) {
		interrupt0();		// Just to set the interrupt flag
		b.interrupt();
		return;
	    }
	}
	interrupt0();
    }

    /**
     * Tests whether the current thread has been interrupted.  The
     * <i>interrupted status</i> of the thread is cleared by this method.  In
     * other words, if this method were to be called twice in succession, the
     * second call would return false (unless the current thread were
     * interrupted again, after the first call had cleared its interrupted
     * status and before the second call had examined it).
     *
     * <p>A thread interruption ignored because a thread was not alive 
     * at the time of the interrupt will be reflected by this method 
     * returning false.
     *
     * @return  <code>true</code> if the current thread has been interrupted;
     *          <code>false</code> otherwise.
     * @see #isInterrupted()
     * @revised 6.0
     */
    public static boolean interrupted() {
	return currentThread().isInterrupted(true);
    }

    /**
     * Tests whether this thread has been interrupted.  The <i>interrupted
     * status</i> of the thread is unaffected by this method.
     *
     * <p>A thread interruption ignored because a thread was not alive 
     * at the time of the interrupt will be reflected by this method 
     * returning false.
     *
     * @return  <code>true</code> if this thread has been interrupted;
     *          <code>false</code> otherwise.
     * @see     #interrupted()
     * @revised 6.0
     */
    public boolean isInterrupted() {
	return isInterrupted(false);
    }

    /**
     * Tests if some Thread has been interrupted.  The interrupted state
     * is reset or not based on the value of ClearInterrupted that is
     * passed.
     */
    private native boolean isInterrupted(boolean ClearInterrupted);
    private native void interrupt0();

interrupt0和isInterrupted(boolean ClearInterrupted);都是调用OS本地方法
interrupt():设置中断标志位

isInterrupted() :判断中是否设置断标志位,只读的

interrupt():如果中断标志位设置了,则返回true,并且清空标志位;如果中断标志位没有设置,返回false,中断标志位还是false。

 

5 涉及到的native方法

    /* Some private helper methods */
    private native void setPriority0(int newPriority);
    private native void stop0(Object o);
    private native void suspend0();
    private native void resume0();
    private native void interrupt0();
    public final native boolean isAlive();
    private native boolean isInterrupted(boolean ClearInterrupted);
    public static native void sleep(long millis) throws InterruptedException;
    public static native Thread currentThread();
    public static native void yield();


6 线程状态

    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;
    }

    /**
     * Returns the state of this thread.
     * This method is designed for use in monitoring of the system state,
     * not for synchronization control.
     * 
     * @return this thread's state.
     * @since 1.5
     */
    public State getState() {
        // get current thread state
        return sun.misc.VM.toThreadState(threadStatus);
    }


 7 超时程序的模板式写法。 参考join方法,需要注意的一个地方是纳秒参数不生效。第二个是join(millis)方法不是直接调用sleep(millis)方法的,

    public final synchronized void join(long millis) 
    throws InterruptedException {
	long base = System.currentTimeMillis();
	long now = 0;

	if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
	}

	if (millis == 0) {
	    while (isAlive()) {
		wait(0);
	    }
	} else {
	    while (isAlive()) {
		long delay = millis - now;
		if (delay <= 0) {
		    break;
		}
		wait(delay);
		now = System.currentTimeMillis() - base;
	    }
	}
    }

wait方法的时间依赖于系统定时器的tick的精度,如果wait(millis)方法休眠时间正好等于外层调用的时间,那么皆大欢喜,直接一个调用就完事了;如果wait(millis)休眠时间大于join的millis,那么wait(delay)也直接返回了;只有当wait(millis)休眠时间小于millis的时候,wailt方法会被多次调用。

 

你可能感兴趣的:(Thread源码)