java.util.concurrent 之 CountDownLatch

CountDownLatch的一个非常典型的应用场景是:有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以继续往下执行。假如我们这个想要继续往下执行的任务调用一个CountDownLatch对象的await()方法,其他的任务执行完自己的任务后调用同一个CountDownLatch对象上的countDown()方法,这个调用await()方法的任务将一直阻塞等待,直到这个CountDownLatch对象的计数值减到0为止。

CountDownLatch是JAVA提供在java.util.concurrent包下的一个辅助类,可以把它看成是一个计数器,其内部维护着一个count计数,只不过对这个计数器的操作都是原子操作,同时只能有一个线程去操作这个计数器,CountDownLatch通过构造函数传入一个初始计数值,调用者可以通过调用CounDownLatch对象的cutDown()方法,来使计数减1;如果调用对象上的await()方法,那么调用者就会一直阻塞在这里,直到别人通过cutDown方法,将计数减到0,才可以继续执行。


CountDownLatch类有3个基本元素:

  1. 初始值决定CountDownLatch类需要等待的事件的数量。
  2. await() 方法, 被等待全部事件终结的线程调用。
  3. countDown() 方法,事件在结束执行后调用。
import java.util.concurrent.CountDownLatch;

public class Sample {
    /**
     * 计数器,用来控制线程
     * 传入参数2,表示计数器计数为2
     */
    private final static CountDownLatch mCountDownLatch = new CountDownLatch(2);

    /**
     * 示例工作线程类
     */
    private static class WorkingThread extends Thread {
        private final String mThreadName;
        private final int mSleepTime;
        public WorkingThread(String name, int sleepTime) {
            mThreadName = name;
            mSleepTime = sleepTime;
        }
        
        @Override
        public void run() {
            System.out.println("[" + mThreadName + "] started!");
            try {  
                    Thread.sleep(mSleepTime);  
            } catch (InterruptedException e) {  
                    e.printStackTrace();  
            }
            mCountDownLatch.countDown();
            System.out.println("[" + mThreadName + "] end!"); 
        }
    }
    
    /**
     * 示例线程类
     */
    private static class SampleThread extends Thread {
        
        @Override
        public void run() {
            System.out.println("[SampleThread] started!");
            try {
                // 会阻塞在这里等待 mCountDownLatch 里的count变为0;
                // 也就是等待另外的WorkingThread调用countDown()
                mCountDownLatch.await();
            } catch (InterruptedException e) {
                
            }
            System.out.println("[SampleThread] end!");
        }
    }
    
    public static void main(String[] args) throws Exception {
        // 最先run SampleThread
        new SampleThread().start();
        // 运行两个工作线程
        // 工作线程1运行5秒
        new WorkingThread("WorkingThread1", 5000).start();
        // 工作线程2运行2秒
        new WorkingThread("WorkingThread2", 2000).start();
    }
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值