【原】CountDownLatch使用

最近遇到一个问题,需要批量的从数据库中读取数据,但是对于数据的处理需要等待一部分完成之后再进行下一批的数据。抽象出来就是一个任务,分成N份来执行,每一份由多个线程去执行,一份完成之后再执行下一份。于是想起了CountDownLatch

网上关于CountDownLatch的文章很多,搜了一些,也大体看了一下,但是感觉最好的还是CountDownLatch官方代码里面的两个例子,现在把这两个例子简单说明一下。

CountDownLatch一个线程同步的工具,是的一个或者多个线程等待其他线程操作完成之后再执行。

CountDownLatch通过一个给定的数值count来进行初始化,方法await()一直阻塞直到当前的count到达零为止,count的数值通过countDown()方法来减1count的数值一旦设定就不能再修改,如果需要进行修改,请考虑使用CyclicBarrier

         大体看了一下源代码,是通过同步队列来作为计数器来进行控制的。同步队列是在CountDownLatch内部实现了一个静态内部类,countDown()通过调用队列来减1

       有两个典型的应用场景:

第一种是一个开始的信号,所有的task任务等待这个信号。类似于百米赛跑中的信号员,所有的运动员都做好准备,等待信号,信号一来,那就开始运行。

    第二种是将一个任务分支N部分由M个线程来处理,等待所有的线程M完成任务后做其他的事情,还是刚才的例子,所有运动员跑完之后,才能知道所有人员的排名情况。

 

public class CountDownLatchTest {
	public static void main(String[] args) throws Exception{
		CountDownLatch s = new CountDownLatch(1);
		CountDownLatch e = new CountDownLatch(6);
		for(int i=0;i<6;i++){	
			new Thread(new Worker(s,e)).start();
		}	
		System.out.println("i am the judge ,now ,i start the singal");
		s.countDown();
		System.out.println("waiting all task over"+e.getCount());
		e.await();
		System.out.println("all is over");
	}
}
class Worker implements Runnable{
	private final CountDownLatch startSingal ;
	private final CountDownLatch endSingal;
	public Worker(CountDownLatch startSingal, CountDownLatch endSingal) {
		super();
		this.startSingal = startSingal;
		this.endSingal = endSingal;
	}

	public void run() {
		try {
			System.out.println(Thread.currentThread().getName()+"waiting the start singal...."+startSingal.getCount());
			//等待开始信号信号
			startSingal.await();
			System.out.println(Thread.currentThread().getName()+"start to executer");
			//结束的计数器减一
			endSingal.countDown();
		} catch (InterruptedException e) {				
			e.printStackTrace();
		}
	}
	
}

   


执行结果:
Thread-0waiting the start singal....1
Thread-2waiting the start singal....1
Thread-1waiting the start singal....1
i am the judge ,now ,i start the singal
waiting all task over6
Thread-1start to executer
Thread-3waiting the start singal....1
Thread-4waiting the start singal....1
Thread-3start to executer
Thread-5waiting the start singal....0
Thread-5start to executer
Thread-2start to executer
Thread-0start to executer
Thread-4start to executer
all is over
 

 

	public static void main(String[] args) throws Exception{
		CountDownLatch latch = new CountDownLatch(6);
		Executor e = Executors.newFixedThreadPool(6);
		System.out.println("thread number is 6,now start");
		for(int i=0;i<6;i++){
			e.execute(new Worker(latch,i));
		}
		System.out.println("waiting all is over ");
		latch.await();
		System.out.println("all is over");
		
	}
}
class Worker implements Runnable{
	private final CountDownLatch number;
	private int temp;
	public Worker(CountDownLatch number, int temp) {
		super();
		this.number = number;
		this.temp = temp;
	}
	public void run() {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {}
		System.out.println(Thread.currentThread().getName()+"runnable  - "+temp);
		number.countDown();
	}
	
}
 写道
thread number is 6,now start
waiting all is over
pool-1-thread-4runnable - 3
pool-1-thread-5runnable - 4
pool-1-thread-1runnable - 0
pool-1-thread-3runnable - 2
pool-1-thread-2runnable - 1
pool-1-thread-6runnable - 5
all is over

猜你喜欢

转载自iamzhongyong.iteye.com/blog/1439310