join()使用场景
当程序希望各个线程执行完后,将他们的计算结果最终合并运算时,换句话说要等待多个线程将子任务执行完后,才能进行合并结果操作,这时候就可以使用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 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;
}
}
}<br /><br /></pre>
有同学疑问,调用join后到底是哪个线程阻塞了?其实很好理解,就是当前执行的线程阻塞,而不是调用join的线程!
public static void main(String[] args) throws InterruptedException {
final Thread t = new Thread(new Runnable() {
public void run() {
try {
System.out.println("t线程开始"+System.currentTimeMillis());
Thread.sleep(2000);
System.out.println("t线程结束"+System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
try {
t.start();
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t2线程结束"+System.currentTimeMillis());
}
});
t2.start();</pre>
Thread.currentThread().sleep(1000);
System.out.println(t2.getState());
System.out.println("t2线程开始"+System.currentTimeMillis());
}</pre>
将上面的测试代码里的join方法,用join的源码替换就一目了然了如下
public static void main(String[] args) throws InterruptedException {
final Thread t = new Thread(new Runnable() {
public void run() {
try {
System.out.println("t线程开始"+System.currentTimeMillis());
Thread.sleep(2000);
System.out.println("t线程结束"+System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
try {
t.start();
//t.join();
//join源码开始
long millis = 0;
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (t.isAlive()) {
//wait就是对t2线程的操作
t.wait(0);
}
} else {
while (t.isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
t.wait(delay);
now = System.currentTimeMillis() - base;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}//join源码结束
System.out.println("t2线程结束"+System.currentTimeMillis());
}
});
t2.start();
System.out.println("t2线程开始"+System.currentTimeMillis());
}</pre>
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于