接上一篇: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");
}
}
图上是显示显示main线程获取到线程对象锁,处于Wait()生效中,而在start()之前调用的join()方法却未生效,说明join必须在该线程执行start()后,线程处于runnable/running状态中才会生效