1.概述
- join方法的主要作用就是同步,它可以使得线程之间的并行执行变为串行执行
2.示例
- thread.join();
- thread.join(long millis); //等待millis时间后串行变成继续并行.
public class JoinThreadTest {
public void a(Thread joinThread) {
System.out.println("方法a执行了...");
joinThread.start();
try {
joinThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("a方法执行完毕...");
}
public void b() {
System.out.println("加塞线程开始执行....");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("加塞线程执行完毕...");
}
/**
方法a执行了...
加塞线程开始执行....
加塞线程执行完毕...
a方法执行完毕...
*/
public static void main(String[] args) {
JoinThreadTest joinThreadTest = new JoinThreadTest();
//准备插入的线程
Thread joinThread = new Thread(new Runnable() {
@Override
public void run() {
joinThreadTest.b();
}
});
//插入到线程
new Thread(new Runnable() {
@Override
public void run() {
joinThreadTest.a(joinThread);
}
}).start();
}
}
3.源码
public class Thread implements Runnable {
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) {
//isAlive是加塞线程,
while (isAlive()) {
//如果子线程存活则让当前线程wait,(wait的是synchronized的对象,而synchronized的是当前对象)
//锁的是外层调用的的线程
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
//Tests if this thread is alive. A thread is alive if it has been started and has not yet died.
//也就是sleep的时候也算是活着.
public final native boolean isAlive();
}
Thread的join方法线程有synchronized修饰,而如果synchronized获得对象锁是线程的实例时,此时比较特殊,当该线程终止的时候,会调用线程自身的notifyAll()方法,会通知所有等待在该线程对象上的线程.
也就是如果加塞线程活着,则将当前线程wait(),当加塞线程完成之后,则会调用自身的notifyall(),然后当前线程notify继续.
因为如果synchronized获得对象锁是线程的实例时,此时比较特殊,当该线程终止的时候,会调用线程自身的notifyAll()方法,会通知所有等待在该线程对象上的线程.
4. 总结
-
join方法要放在start后面,如果放在start前,并不能起到同步的作用
参考文章:Java中的join方法原理详解