题目
* 1. 现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,
* 并且 T3 线程在 T2 之后执行?
代码
package com.javabase;
/**
* 1. 现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,
* 并且 T3 线程在 T2 之后执行?
* @author jiyu
*
*/
public class JoinTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread t1=new Thread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("t1");
}
});
Thread t2=new Thread(new Runnable(){
@Override
public void run() {
t1.start();
try {
t1.join();//join()合并线程,子线程运行完之后,主线程才开始执行
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// TODO Auto-generated method stub
System.out.println("t2");
}
});
Thread t3=new Thread(new Runnable(){
@Override
public void run() {
t2.start();
try {
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// TODO Auto-generated method stub
System.out.println("t3");
}
});
t3.start();
// 顺序启动,是不能确保t1>t2>t3
// t1.start();
// t2.start();
// t3.start();
}
}
解析
join的原理
任何地方当调用了t.join(),就必须要等待线程t执行完毕后,才能继续执行其他线程。这里其实是运用了Java中最顶级对象Object提供的方法wait()。wait()方法用于线程间通信,它的含义是通知一个线程等待一下,让出CPU资源,注意这里是会放弃已经占有的资源的。直到t线程执行完毕,再调用notify()唤醒当前正在运行的线程
源码
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;
}
}
}