java.util.concurrent.CountDownLatch组件说明

一、CountDownLatch

1、功能说明:同步一个或者多个任务,强制它们等待由其它任务执行的一组操作完成。

2、注意事项:CountDownLatch被设计为只触发一次,计数值不能被重置,如果需要重置计数值的版本,请使用CyclicBarrier。

3、主要方法之构造方法CountDownLatch(int count)参数必须大于0的整数,这表示计数初始值。

4、主要方法之等待CountDownLatch.awit()等待计数值到达0。

5、主要方法之减少计数值CountDownLatch.countDown()将计数值减1。

6、如下例所示,同时执行多个任务,并且等待任务完成,在日常开发中常用于将业务分解成多个任务例用线程并行处理 ,充分发挥多线程的优势,当然也要注意限制线程数量,毕竟线程的开销也是不小的。

package org.com.jsoup;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountDownLatchTest {

	/**
	 * @param args
	 * @throws InterruptedException 
	 */
	public static void main(String[] args) throws InterruptedException {
		//定义10个线程
		final int theadMax = 10;
		//初使化10要与线程交互的锁存器
		final CountDownLatch downLatch = new CountDownLatch(theadMax);
		//定义一个线程执行器 创建固定大小(nThreads,大小不能超过int的最大值)的线程池
		final ExecutorService exec = Executors.newFixedThreadPool(theadMax);
		//记录开始时间,以纳秒为单位
	    final long beginTime =	 System.nanoTime();
		for(int i=0;i<theadMax;i++){
			Runnable runable = new Runnable(){
				@Override
				public void run() {
					try {
						//要执行的业务逻辑
						Thread.sleep(10);
					} catch (InterruptedException e) {
						//处理异常
					}finally{
						//减少计数值
						System.out.println(String.format("线程:%s执行完成,当时时间:%d", Thread.currentThread().getName(),System.nanoTime()));
						downLatch.countDown();	
					}
				}
			};
			//将任务放入线程池执行
			exec.execute(runable);
			}
			//在这里等待所有的线程执行完
			downLatch.await();
			//关闭线程池
			exec.shutdown();
		    System.out.println("执行完毕,用时:" +( System.nanoTime() -beginTime) + "纳秒");

	}

}

7、既然是分解任务,又如何提取每个线程返回的结果呢?那么用下例来试试如何。

public static void test3() throws InterruptedException, ExecutionException{
		//定义10个线程
		final int theadMax = 10;
		//初使化10要与线程交互的锁存器
		final CountDownLatch downLatch = new CountDownLatch(theadMax);
		//定义存储计算结果的集合
		final List< String> list = new ArrayList<String>();
		final ExecutorService exec = Executors.newFixedThreadPool(theadMax);
		//记录开始时间,以纳秒为单位
	    final long beginTime =	 System.nanoTime();
		for(int i=0;i<theadMax;i++){
			Runnable runable = new Runnable(){
				@Override
				public void run() {
					try {
						//要执行的业务逻辑
						Thread.sleep(10);
					} catch (InterruptedException e) {
						//处理异常
					}finally{
						//减少计数值
						System.out.println(String.format("线程:%s执行完成,当时时间:%d", Thread.currentThread().getName(),System.nanoTime()));
						//这里需要同步吗?
						list.add("线程名称:" + Thread.currentThread().getName());
						downLatch.countDown();	
					}
				}
			};
			//将任务放入线程池执行
			exec.execute(runable);
			}
			//在这里等待所有的线程执行完
			downLatch.await();
			//关闭线程池
			exec.shutdown();
			//浏览所有的计算结果
			for (String value : list) {
				 //取得结果
				 System.out.println(value);
			}
		    System.out.println("执行完毕,用时:" +( System.nanoTime() -beginTime) + "纳秒");
	}

8、对于上面的提取每个线程的返回结果的方案有更好的吗?看看下面的例子。 

public static void test2() throws InterruptedException, ExecutionException{
		//定义10个线程
				final int theadMax = 10;
				//定义一个线程执行器,并可以取得第个线程执行后的结果 创建固定大小(nThreads,大小不能超过int的最大值)的线程池
				final ExecutorService exec = Executors.newFixedThreadPool(theadMax);
				final ExecutorCompletionService<String> futureExec = new ExecutorCompletionService<String> (exec);
				//定义一个存储可以异步取得返回值的Future集合
				final List< Future<String>> list = new ArrayList< Future<String>>();
				//记录开始时间,以纳秒为单位
			    final long beginTime =	 System.nanoTime();
				for(int i=0;i<theadMax;i++){
					Callable<String> task = new Callable<String>(){
						@SuppressWarnings("finally")
						@Override
						public String call() {
							try {
								//要执行的业务逻辑
								Thread.sleep(10);
							} catch (InterruptedException e) {
								//处理异常
							}finally{
								//减少计数值
								System.out.println(String.format("线程:%s执行完成,当时时间:%d", Thread.currentThread().getName(),System.nanoTime()));
								return Thread.currentThread().getName();
							}
						}
					};
					//将任务放入线程池执行
					list.add(futureExec.submit(task));
					}
					for (Future<String> future : list) {
						 //取得异步计算结果
						 System.out.println(	future.get());
					}
					//关闭线程池
					exec.shutdown();
				    System.out.println("执行完毕,用时:" +( System.nanoTime() -beginTime) + "纳秒");
	}

 

你可能感兴趣的:(并发,Concurrent,CountDownLatch)