Thread的join()源代码分析(6)

接上一篇:Thread的setPriority()设置优先级源代码分析(5)

今天我们来看Thread的join();

public final void join(long millis)
    等待该线程终止的时间最长为 millis 毫秒。超时为 0 意味着要一直等下去。
    参数:millis- 以毫秒为单位的等待时间。
    抛出:InterruptedException- 如果任何线程中断了当前线程。当抛出该异常时,当前线程的中断状态 被清除

public final void join(long millis,int nanos)

      等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒。

      参数:millis - 以毫秒为单位的等待时间。nanos - 要等待的 0-999999 附加纳秒。

      抛出:IllegalArgumentException - 如果 millis 值为负,则 nanos 的值不在 0-999999 范围内。

 InterruptedException - 如果任何线程中断了当前线程。当抛出该异常时,当前线程的中断状态 被清除。

public final void join()

    等待该线程终止。

    抛出:InterruptedException - 如果任何线程中断了当前线程。当抛出该异常时,当前线程的中断状态 被清除。

public final void join() throws InterruptedException {
        join(0);
    }
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;
            }
        }
    }
 public final synchronized void join(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++;
        }

        join(millis);
    }

这里执行join()时关键字synchronized,锁是该对象实例(this),通过Object的本地方法wait(秒数),而Wait()方法调用时释放锁资源,当main线程调用一个线程的join方法,main线程会获得线程对象的锁,调用wait(等待时间),直到该对象唤醒main线程(时间到了或者线程执行结束)。

下面贴出实现代码:

import static java.lang.Thread.sleep;

class JoinD implements Runnable{

	@Override
	public void run() {
			for (int i = 0; i < 60; i++) {
				try {
					sleep(5_000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+"..."+i);
		}
	}
}
public class JoinDemo {
	public static void main(String[] args) throws InterruptedException {
		JoinD j = new JoinD();
		Thread t1 = new Thread(j,"t1");
		Thread t2 = new Thread(j,"t2");
		t1.join();
		System.out.println("main is run");
		t1.start();
		t2.start();
		t1.join(100_000);
		for (int i = 0; i < 80; i++) {
			System.out.println("main....run"+i);
			Thread.sleep(12_000);
			System.out.println("is over");
		}
		System.out.println("over");
	}
}

Thread的join()源代码分析(6)_第1张图片

图上是显示显示main线程获取到线程对象锁,处于Wait()生效中,而在start()之前调用的join()方法却未生效,说明join必须在该线程执行start()后,线程处于runnable/running状态中才会生效

你可能感兴趣的:(菜鸟成长之路)