当前位置:编程学习 > JAVA >>

JDK-CountDownLatch-实例、源码和模拟实现

根据CountDownLatch的document,就是说CountDownLatch作为一个同步的助手,可以阻塞一个线程,等待另一个线程结束了再执行。
所以CountDownLatch的作用在于:通过阻塞来协调线程间的执行顺序。
CountDownLatch最重要的方法为await()和countDown()。首先,初始化指定一个count,每次countDown()都会count--,而await()就是阻塞调用它的方法,直到count==0。
所以可以把CountDownLatch看成同步的计数器,什么时候倒数到0就执行,否则阻塞。
 
Demo
我们首先做一个CountDownLatch的demo,看看它是怎么一个阻塞。
count初始化为2,所以count.await()会阻塞主线程,直到两个processor都countDown(),即count==0的时候才会执行,打印出"Processors has been done."
[java]  
public class CountDownLatchTest {  
    public static void main(String[] args) throws InterruptedException {  
        CountDownLatch count = new CountDownLatch(2);  
        ExecutorService exc = Executors.newSingleThreadExecutor();  
          
        System.out.println("Before submit the processor.");  
        exc.submit(new CountProcessor(count, "P1"));  
        exc.submit(new CountProcessor(count, "P2"));  
        System.out.println("Has submited the processor.");  
  
        count.await();  
        System.out.println("Processors has been done.");  
        exc.shutdown();  
    }  
}  
  
class CountProcessor extends Thread {  
    private CountDownLatch count;  
    private String name;  
    public CountProcessor(CountDownLatch count, String name) {  
        this.count = count;  
        this.name = name;  
    }  
    @Override  
    public void run() {  
        try {  
            Thread.currentThread().sleep(1000);  
            System.out.println(this.name + " has been done.");  
            count.countDown();  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
    }  
}  
 
 
修改一下上面的程序,我们可以模拟一个百米赛跑的现场:
首先运动员进场:前期数据准备和线程池的初始化。
准备工作完成后统一起跑:传入的begin.await()一直阻塞着Runner.run(),在前期准备完成后,begin.countDown()后begin.count==0,阻塞结束,Runner起跑。
比赛一直进行,直到所有选手冲过终点:end.await()会阻塞主线程,所以最后的那条print语句不会提前打印,而是等待Runner.run()结束执行end.countDown(),减少3次直到end.count==0才接触阻塞,宣布比赛结束。
这就是CountDownLatch的经典场景,统一开始,统一结束。
[java] 
public class CountDownLatchTest {  
    public static void main(String[] args) throws InterruptedException {  
        CountDownLatch begin = new CountDownLatch(1);  
        CountDownLatch end = new CountDownLatch(3);  
        ExecutorService exc = Executors.newCachedThreadPool();  
          
        System.out.println("Runners are comming.");  
        exc.submit(new CountProcessor(begin, end, "Runner_1", 1000));  
        exc.submit(new CountProcessor(begin, end, "Runner_2", 2000));  
exc.submit(new CountProcessor(begin, end, "Runner_3", 3000));  
        System.out.println("Ready.");  
          
        Thread.currentThread().sleep(1000);  
        System.out.println("Go.");  
        begin.countDown();  
          
        end.await();  
        System.out.println("All runners Finish the match.");  
        exc.shutdown();  
    }  
}  
  
class CountProcessor extends Thread {  
    private CountDownLatch beginCount;  
    private CountDownLatch endCount;  
    private String name;  
    private int runningTime;  
    public CountProcessor(CountDownLatch beginCount, CountDownLatch endCount, String name, int runningTime) {  
        this.beginCount = beginCount;  
        this.endCount = endCount;  
        this.name = name;  
        this.runningTime = runningTime;  
    }  
  
    @Override  
    public void run() {  
        try {  
            this.beginCount.await();  
            System.out.println(this.name + " start.");  
            Thread.currentThread().sleep(this.runningTime);  
            System.out.println(this.name + " breast the tape.");  
            this.endCount.countDown();  
        } catch (InterruptedException e) {  
            e.printStackTrace();  
        }  
    }  
}  
 
 
Source Code
我们来看JDK中CountDownLatch是怎么定义的,以及其中的主要方法。
[java] 
public class CountDownLatch {  
public CountDownLatch(int count) {  
        if (count < 0) throw new IllegalArgumentException("count < 0");  
        this.sync = new Sync(count);  
}  
  
public void await() throws InterruptedException {  
        sync.acquireSharedInterruptibly(1);  
}  
  
public void countDown() {  
        sync.releaseShared(1);  
}  
  
public long getCount() {  
        return sync.getCount();  
}  
}  
 
&n
补充:软件开发 , Java ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,