浅谈CountDownLatch类

来源:互联网 发布:翻译准确的软件 编辑:程序博客网 时间:2024/05/17 22:50

      最近在研究类似于迅雷的多线程下载,写好代码后就会有测试多线程效率这么一个环节,于是就遇见了如何统计多个线程执行时间的问题,即从第一个线程启动,到最后一个线程执行完毕所消耗的时间。我们知道,当一个主方法启动完成N个线程后,不会等到N个线程执行完毕才结束方法,所以这里该如何监听每个线程的执行完成与否的状态呢?

     CountDownLatch,是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。此类的工作原理大致是:首先存在一个锁存器计数器,先指定好锁存器中盛放的线程个数,比如3个,每当执行一次countDown()方法,锁存器倒计数就会减1,直至锁存器中的数字减为0时,触发await()方法,让处于阻塞状态的主方法重新恢复非阻塞状态,从而有效的保证了每个线程执行完毕。

      此类具备一个构造器和五个方法:

        构造器:CountDownLatch(int count)  count-指定锁存器中盛放的线程个数

       方法:    await() - 使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断

            await(long timeout,TimeUnit unit) - 使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间。timeout是等待时间,unit是时间单位。

            countDown() - 递减锁存器的计数,如果计数到达零,则释放所有等待的线程。

            getCount() - 返回当前计数。

            toString() - 返回标识此锁存器及其状态的字符串。

   不多废话,先上代码:

package downLoad;

import java.util.concurrent.CountDownLatch;

public class Test {

    private static Test test;
    private CountDownLatch cdl;
    
    private Test(){
        cdl = new CountDownLatch(3);
    }
    
    public CountDownLatch getCdl(){
        return cdl;
    }
    
    public static Test getInstance(){
        if(test == null){
            test = new Test();
        }
        return test;
    }
    
    public static void main(String[] args) {
        
        //初始化COuntDownLatch
        Test.getInstance();
        
        //开始时间
        long start = System.currentTimeMillis();
        for(int i=0;i<3;i++){
            new TestThread().start();;
        }
        //让主线程处于阻塞状态,直到其他线程执行完毕再唤醒
        try {
            getInstance().getCdl().await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("耗时:"+(System.currentTimeMillis()-start)+"毫秒");
        
    }
    
    public static class TestThread extends Thread{

        @Override
        public void run() {
            String str = "";
            for(int i=0;i<10000;i++){
//                System.out.println(i);
                str += i;
            }
            System.out.println(Thread.currentThread().getName()+" is over...");
            Test.getInstance().getCdl().countDown();
        }
        
    }
    
}


在Test类中,定义了全局变量CountDownLatch对象,以及一个内部线程类,通过代码我们就能够明白CountDownLatch的用法了。

0 0