引言

  随着互联网时代的发展。在Java编程中多线程来处理多任务降低任务响应时间已是一种趋势。这里主要讲解Java多线程入门的主线程等待子线程结束的几种方法。

一.通过线程的join()方法

通过join()方法来实现主线程等待子线程同步的例子如下
首先编写一个简单的测试用的线程类:
 
package xqlee.net.project.demo.thread.waitchilds;

public class ThreadChildOne extends Thread {


	public ThreadChildOne(String name) {
		super(name);
	}

	@Override
	public void run() {
		try {
			long time=1000 * ((int) (Math.random() * 10));
			System.out.println("From Child:" + this.getName()+">>>Start["+time+"]");
			sleep(time);
			System.out.println("From Child:" + this.getName()+">>>End");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
这里通过继承Thread来编写的一个线程类。

编写一个测试类来实现:
package xqlee.net.project.demo.thread.waitchilds;

import java.util.ArrayList;
import java.util.List;

public class TestWaitChildsOne {

	public static void main(String[] args) {

		try {
			System.out.println("From Main Thread:==>Start");
			System.out.println("From Main Thread:开始调用子线程----》");
			long start = System.currentTimeMillis();
			List<ThreadChildOne> list = new ArrayList<>();
			for (int i = 0; i < 6; i++) {
				ThreadChildOne threadChild = new ThreadChildOne("Child-" + i);
				threadChild.start();
				list.add(threadChild);
			}

			for (ThreadChildOne threadChild : list) {
				threadChild.join();
			}
			System.out.println("From Main Thread:子线程调用结束,耗时:" + (System.currentTimeMillis() - start));
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

执行测试类,观察控制台如下图:
通过join()实现线程同步的运行结果
从上图我们可以看到成功的实现了主线程等待子线程同步。观察这里比最大子线程耗时多了3毫秒,可能是因为CPU切换线程耗时属于正常现象。
 

二.通过JDK自带的工具类CountDownLatch来实现多线程的线程同步

编写一个简单的测试线程类:
package xqlee.net.project.demo.thread.waitchilds;

import java.util.concurrent.CountDownLatch;

public class ThreadChildTwo extends Thread {
	private CountDownLatch countDownLatch;

	public ThreadChildTwo(String name, CountDownLatch countDownLatch) {
		super(name);
		this.countDownLatch = countDownLatch;
	}

	@Override
	public void run() {
		try {
			long time = 1000 * ((int) (Math.random() * 10));
			System.out.println("From Child:" + this.getName() + ">>>Start[" + time + "]");
			sleep(time);
			System.out.println("From Child:" + this.getName() + ">>>End");

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 倒数器减1
			countDownLatch.countDown();
		}
	}
}

测试类:
package xqlee.net.project.demo.thread.waitchilds;

import java.util.concurrent.CountDownLatch;

public class TestWaitChildsTwo {

	public static void main(String[] args) {
		try {// 创建一个初始值为5的倒数计数器  
	        CountDownLatch countDownLatch = new CountDownLatch(5);  //这里的数字=线程数+1
			System.out.println("From Main Thread:==>Start");
			System.out.println("From Main Thread:开始调用子线程----》");
			long start = System.currentTimeMillis();
			for (int i = 0; i < 5; i++) {
				ThreadChildTwo threadChild = new ThreadChildTwo("Child-" + i,countDownLatch);
				threadChild.start();
			}
			  // 阻塞当前线程,直到倒数计数器倒数到0  
            countDownLatch.await();  
        	System.out.println("From Main Thread:子线程调用结束,耗时:" + (System.currentTimeMillis() - start));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

运行结果:
测试运行结果