线程同步工具类-CountDownLatch

  CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。

    CountDownLatch是通过一个计数器来实现的,计数器的初始值为线程的数量。每当一个线程完成了自己的任务后,计数器的值就会减1。当计数器值到达0时,它表示所有的线程已经完成了任务,然后在闭锁上等待的线程就可以恢复执行任务。


   CountDownLatch类只提供了一个构造器:

public CountDownLatch(int count) {  };  //参数count为计数值

    然后下面这3个方法是CountDownLatch类中最重要的方法:

public void await() throws InterruptedException { };   //调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };  //和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public void countDown() { };  //将count值减1

  在实时系统中的使用场景

      让我们尝试罗列出在java实时系统中CountDownLatch都有哪些使用场景。我所罗列的都是我所能想到的。如果你有别的可能的使用方法,请在留言里列出来,这样会帮助到大家。

       实现最大的并行性:有时我们想同时启动多个线程,实现最大程度的并行性。例如,我们想测试一个单例类。如果我们创建一个初始计数为1的CountDownLatch,并让所有线程都在这个锁上等待,那么我们可以很轻松地完成测试。我们只需调用 一次countDown()方法就可以让所有的等待线程同时恢复执行。

      开始执行前等待n个线程完成各自任务:例如应用程序启动类要确保在处理用户请求前,所有N个外部系统已经启动和运行了。

      死锁检测:一个非常方便的使用场景是,你可以使用n个线程访问共享资源,在每次测试阶段的线程数目是不同的,并尝试产生死锁。

CountDownLatch使用例子:

  创建数量的线程,并发执行任务:

public class CountdownLatchTest {

	public static void main(String[] args) throws Exception {
		final CountDownLatch startGate=new CountDownLatch(1);
		final CountDownLatch endGate=new CountDownLatch(3);
		for (int i = 0; i < 3; i++) {
			Thread thread=new Thread(){
				@Override
				public void run() {
					try {
						startGate.await();
						Thread.sleep(1000);
						System.out.println("任务: "+Thread.currentThread().getName() +" 执行业务处理.......");
					} catch (Exception e) {
						
					}finally{
						endGate.countDown();
					}
				}
			};
			thread.start();
		}
		System.out.println("-----------------------------");
		long start=System.currentTimeMillis();
		startGate.countDown();
		System.out.println("已发送命令,正在等待结果");
		endGate.await();
		long end=System.currentTimeMillis();
		System.out.println("执行时间:"+(end-start));
	}
	
}

参考资料:

  http://www.importnew.com/15731.html

  http://ifeve.com/talk-concurrency-countdownlatch/

发表评论