Java中经常存在以下的需求,启动多个相同或者不同的线程,主线程需要等待所有的线程执行完才继续往下执行
要实现上面的需求,基本的思路: 创建一个计数器, 来记录线程的执行
有两种实现方法
方法1:
使用锁和计数器:需要有一个对象锁,作用一:保证这个计数器的线程安全,作用二:阻塞主线程,等待所有线程执行完再来唤醒主线程继续执行
方法2:
使用Java线程包中的CountDownLatch:不需要加锁, 不需要wait notify这么复杂
方法1:
package com.yaya.thread.threadCount.count;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestCount {
	int count = 0;
	int total = 0;
	Object object = new Object();
	void testCount() {
		total = 10;
		ExecutorService pool = Executors.newFixedThreadPool(5);
		for (int i = 0; i < 10; i++) {
			final int j = i;
			Runnable runnable = new Runnable() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					try {
						System.out.println("runnalbe:" + j);
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} finally {
						synchronized (object) {
							count++;
							if (count == total) {
								object.notify();
							}
						}
					}
				}
			};
			pool.execute(runnable);
		}
		synchronized (object) {
			if (count != total) {
				try {
					object.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		System.out.println("end");
		pool.shutdown();
	}
	public static void main(String[] args) {
		TestCount testCount = new TestCount();
		testCount.testCount();
	}
} 
方法2: CountDownLatch
package com.yaya.thread.threadCount.countDownLatch;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import com.yaya.thread.future.ThreadPoolUtil;
public class TestCountDownLatch {
	static CountDownLatch count = null;
	
	public void testRunnalbe(){
		List<String> list = new ArrayList<String>();
		for (int i = 1; i <= 10; i++) {
			list.add("list" + i);
		}
		count = new CountDownLatch(list.size());
		List<Runnable> runnables = new ArrayList<Runnable>();
		for (int i = 0; i < list.size(); i++) {
			final String listName = list.get(i);
			Runnable runnable = new TestRunnable1(listName, count);
			runnables.add(runnable);
		}
		try {
			ThreadPoolUtil.exeRunnableList(runnables);
		} catch (Exception e) {
			System.err.println(e.getMessage());
		}
		try {
			count.await();
			System.out.println("end");
			ThreadPoolUtil.shutDown(true);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	public void testDifferentRunnalbes(){
		List<String> list = new ArrayList<String>();
		for (int i = 1; i <= 10; i++) {
			list.add("list" + i);
		}
		count = new CountDownLatch(list.size()*2);
		List<Runnable> runnables = new ArrayList<Runnable>();
		for (int i = 0; i < list.size(); i++) {
			final String listName = list.get(i);
			Runnable runnable = new TestRunnable1(listName, count);
			runnables.add(runnable);
		}
		
		for (int i = 0; i < list.size(); i++) {
			final String listName = list.get(i);
			Runnable runnable = new TestRunnable2(listName, count);
			runnables.add(runnable);
		}
		try {
			ThreadPoolUtil.exeRunnableList(runnables);
		} catch (Exception e) {
			System.err.println(e.getMessage());
		}
		try {
			count.await();
			System.out.println("end");
			ThreadPoolUtil.shutDown(true);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static void main(String[] args) {
		TestCountDownLatch  testCountDownLatch  = new TestCountDownLatch();
		testCountDownLatch.testDifferentRunnalbes();
	}
}package com.yaya.thread.threadCount.countDownLatch;
import java.util.concurrent.CountDownLatch;
public class TestRunnable2 implements Runnable {
	String appid;
	CountDownLatch count;
	public TestRunnable2(String appid, CountDownLatch count) {
		super();
		this.appid = appid;
		this.count = count;
	}
	@Override
	public void run() {
		System.out.println("task" + this.appid + "开始");
		try {
			Thread.sleep(3000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("task" + this.appid + "睡了3s");
		count.countDown();
	}
} 
package com.yaya.thread.future;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadPoolUtil {
	// 线程池
	private static ThreadPoolExecutor threadPool;
	// 线程池核心线程数
	private static final int CORE_POOL_SIZE = 5;
	// 线程池最大线程数
	private static final int MAX_POOL_SIZE = 10;
	// 额外线程空状态生存时间
	private static final int KEEP_ALIVE_TIME = 10000;
	private static final int CANCEL_TASK_TIME = 20;
	private ThreadPoolUtil() {
	}
	static {
		threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS,
				new LinkedBlockingQueue<>(30), new ThreadFactory() {
					private final AtomicInteger integer = new AtomicInteger();
					@Override
					public Thread newThread(Runnable r) {
						return new Thread(r, "mock thread:" + integer.getAndIncrement());
					}
				});
	}
	/**
	 * 从线程池中抽取线程,执行指定的Runnable对象
	 * 
	 * @param runnable
	 */
	public static void execute(Runnable runnable) {
		threadPool.execute(runnable);
	}
	/**
	 * 批量执行 Runnable任务
	 * 
	 * @param runnableList
	 */
	public static void exeRunnableList(List<Runnable> runnableList) {
		for (Runnable runnable : runnableList) {
			threadPool.execute(runnable);
		}
	}
	/**
	 * 从线程池中抽取线程,执行指定的Callable对象
	 * 
	 * @param callable
	 * @return 返回执行完毕后的预期结果
	 */
	public static Future exeCallable(Callable<String> callable) {
		return threadPool.submit(callable);
	}
	/**
	 * 批量执行 Callable任务
	 * 
	 * @param callableList
	 *            callable的实例列表
	 * @return 返回指定的预期执行结果
	 */
	public static List<Future<String>> exeCallableList(List<Callable<String>> callableList) {
		List<Future<String>> futures = null;
		try {
			for (Callable<String> task : callableList) {
				threadPool.submit(task);
			}
			futures = threadPool.invokeAll(callableList);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return futures;
	}
	/**
	 * 批量执行 Callable任务, 但不等待执行完
	 * 
	 * @param callableList
	 *            callable的实例列表
	 * @return 返回指定的预期执行结果
	 */
	public static void exeCallableListNoReturn(List<Callable<String>> callableList) {
		for (Callable<String> task : callableList) {
			threadPool.submit(task);
		}
	}
	/**
	 * 中断任务的执行
	 * 
	 * @param isForceClose
	 *            true:强制中断 false:等待任务执行完毕后,关闭线程池
	 */
	public static void shutDown(boolean isForceClose) {
		if (isForceClose) {
			threadPool.shutdownNow();
		} else {
			threadPool.shutdown();
		}
	}
	/**
	 * 若超出CANCEL_TASK_TIME的时间,没有得到执行结果,则尝试中断线程
	 * 
	 * @param future
	 * @return 中断成功,则返回true 否则返回false
	 */
	public static boolean attemptCancelTask(Future future) {
		boolean cancel = false;
		try {
			future.get(CANCEL_TASK_TIME, TimeUnit.MINUTES);
			cancel = true;
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		} catch (TimeoutException e) {
			cancel = future.cancel(true);
			e.printStackTrace();
		}
		return cancel;
	}
} 
 
                     
            
        













 
                    

 
                 
                    