Java多线程之CountDwonLatch

CountDwonLatch是一个非常实用的多线程控制工具类,这个工具类通常用来控制线程等待,它可以让某个线程等待直到其它线程执行任务结束,在开始执行。下面先看代码,根据代码分析程序,提出问题。
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountDownLatchDemo implements Runnable {
    private static CountDownLatch lock = new CountDownLatch(100);
    private static CountDownLatchDemo task = new CountDownLatchDemo();

    @Override
    public void run() {
        //模拟任务
        try {
            Thread.sleep(3);
            System.out.println("线程" + Thread.currentThread().getName());
            lock.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ExecutorService service = Executors.newFixedThreadPool(5);
        for (int  i = 0; i < 100; ++i) {
            service.submit(task);
        }
        lock.await();
        System.out.println("主线程执行了");
        service.shutdown();
    }
}
代码第六行生成一个CountDwonLatch实例。计数量为100(有点类似与一组信号量)。在这段代码中这表示需要100个线程完成任务,等待在CountDwonLatch上的线程才能继续往下执行。最后的执行结果即主线程等待线程池中提交任务执行结束后,才会接着继续执行。那么就有一个疑问:当前情况是在拥有5个线程的线程池中提交了100个任务。即100个任务执行完成后,100个计数被消耗后,主线程才开始执行。这样看的话,CountDwonLatch中的计数数量就仅仅作为一个辅助的县城管理工具,每个线程执行一次,自身减一,只到计数量为0。如果是这样,那么使用单线程循环执行100次,同样可以达到相同的结果,下面编程验证:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CountDownLatchDemo2 implements Runnable {
    private static CountDownLatchDemo2 task = new CountDownLatchDemo2();
    private static CountDownLatch lock = new CountDownLatch(100);

    @Override
    public void run() {
        try {
            int i = 0;
            while (i++ < 100) {
                Thread.sleep(3);
                System.out.println("线程:" + Thread.currentThread().getName());
                lock.countDown();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ExecutorService service = Executors.newFixedThreadPool(1);
        for (int  i = 0; i < 1; ++i) {
            service.submit(task);
        }

        lock.await();
        System.out.println("主线程执行了");
        service.shutdown();
    }
}
测试情况为在单线程的线程池中,提交了单次任务,在线程任务中,循环100次。经过测试发现,主线程同样是在线程池中线程任务执行完后,继续执行。

经过上面的测试,我们看以看出CountDwonLatch本身是一个不与线程耦合的计数器,每执行一次countDown()方法,计数器数量减一。直到减为0为止,等待在CountDwonLatch才会有执行机会。这样我们可以大胆的猜测,如果CountDwonLatch本身的计数器一旦被消耗完(即为0时),等待其上面的线程即获得了执行权,不在被阻塞。(经测试,确实是这样)。它本身只充当一个线程辅助工具类。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值