作用:使当前线程交换执行权,等待另一个线程执行完毕后,继续执行。
目的:是为了将并行的执行变成串行的执行。
场景:线程 thread1 和 线程 thread2 同是执行,但是 线程 thread2 调用了join 方法后,就进入等待状态 wait。直到 thread1 执行完毕后执行。
package com.liukai.thread.join;
/**
* @author liukai
* @since 2019/6/7 16:05.
*/
public class JoinTest2 {
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new JoinA());
thread1.start();
Thread thread2 = new Thread(new JoinB(thread1));
thread2.start();
}
}
class JoinA implements Runnable {
@Override
public void run() {
System.out.println("thread1 线程启动");
for (int i = 0; i<10; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread1 -> " + i);
}
}
}
class JoinB implements Runnable {
private Thread thread1;
public JoinB(Thread thread1) {
this.thread1 = thread1;
}
@Override
public void run() {
try {
System.out.println("thread2 线程启动");
System.out.println("thread2 调用 thread1.join 方法, 并等待 thread1 执行结束后执行");
thread1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (int i = 0; i < 10; i++) {
System.out.println("thread2 -> " + i);
}
}
}
为什么 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");
}
// millis 0 表示无限等待下去
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
通过 while 轮询 isAlive 方法,判断 thread2 是否一直存活,保证可以有效的 wait 下去,直到被唤醒。
/**
* Tests if this thread is alive. A thread is alive if it has
* been started and has not yet died.
*
* @return <code>true</code> if this thread is alive;
* <code>false</code> otherwise.
*/
public final native boolean isAlive();
网友评论