您的位置:首页 > 编程语言

代码详解のThread.join()实现多个线程顺序执行

2017-09-25 15:37 477 查看
多线程开发中经常遇到线程间的依赖问题,比如:

       线程T2的运行依赖线程T1的执行结果,线程T3的运行依赖线程T2和线程T4的执行结果,此时 T2和T4是可以并行计算的。

遇到这种问题我们就可以使用Thread.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;
}
}
}


举个栗子:

如果在线程t2中我们调用了线程t1的t1.join(默认0ms)方法,意思是:如果线程t1.isAlive(),即线程t1没有结束,则线程t2 wait(0);即t2一直等待。

代码实现如下:

public class Thread1Test extends Thread{

public void run(){
System.out.println("thread1 开始执行");
try {
Thread.sleep(1000);//do something
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread1 执行结束");
}

}

public class Thread2Test extends Thread {
private Thread1Test t1;
public Thread2Test(Thread1Test thread1Test){
this.t1 = thread1Test;
}
public void run(){
System.out.println("thread2 开始执行");
// t2 ...do something;
try {
System.out.println("thread2 开始等待 t1执行");
t1.join(2000);
System.out.println("t1执行结束 thread2 开始继续执行");
//Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread2 执行结束");
}
}

public class Thread3Test extends Thread{

private Thread2Test t2;
private Thread4Test t4;
public Thread3Test(Thread2Test thread2Test,Thread4Test thread4Test){
this.t2 = thread2Test;
this.t4 = thread4Test;
}

public void run(){
System.out.println("thread3 开始执行");
// t3 ...do otherthing;
try {
t4.start();
System.out.println("thread3 开始等待 t2执行");
t2.join();
t4.join();

System.out.println("t2 执行结束 thread3 继续执行");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread3 执行结束");
}
}

public class Thread4Test extends Thread{

public void run(){
System.out.println("thread4 开始执行");
try {
Thread.sleep(4000);//do something
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread4 执行结束");
}

}

public class ThreadMain {

public static void main(String[] args) throws InterruptedException {
Thread1Test t1 = new Thread1Test();
Thread2Test t2 = new Thread2Test(t1);
Thread4Test t4 = new Thread4Test();
Thread3Test t3 = new Thread3Test(t2,t4);
System.out.println("main 线程开始执行");
t1.start();
t2.start();
t3.start();
t3.join();//main 线程会等待线程3执行结束后 才结束
System.out.println("main 线程执行结束");
}

}


运行结果如下:

main 线程开始执行

thread1 开始执行

thread2 开始执行

thread2 开始等待 t1执行

thread3 开始执行

thread3 开始等待 t2执行

thread4 开始执行

thread1 执行结束

t1执行结束 thread2 开始继续执行

thread2 执行结束

thread4 执行结束

t2 执行结束 thread3 继续执行

thread3 执行结束

main 线程执行结束

从运行结果可以看出:t1和t2依次运行,t2和t4运行结束后,t3开始继续运行,最后是main线程执行结束
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: