Java 并发编程学习笔记(7) ----CountDownLatch

CountDownLatch 的使用

1.介绍

此类所提供的功能是判断count计数不为0时则呈wait状态,在屏障处等待它也是一个同步功能的辅助类:
给定一个计数,当使用这个CountDownLatch的类的线程判断计数不为0时,则呈wait状态,如果为0则继续
运行。

2.实现

实现等待与继续运行的效果分别需要使用awiat()和countDown()方法来进行。调用await()方法时判断
计数是否为0,如果不为0则呈等待状态,其他线程可以countDown()方法将计数减1,计数为0时,等待的线
程就继续运行。getCount() 就是获得当前的计数个数。此计数无法被重置。

3.一个具体的跑步比赛

代码


/**
 * CountDownLatch 是一个同步功能的辅助类,使用效果是给定一个计数
 * 当使用这个 CountDownLatch 的线程判断技术不为0 时则当前线程呈wait状态
 * 为0则继续运行
 */
package com.lhc.concurrent.countDownLatch;

import java.util.concurrent.CountDownLatch;

public class MyThread extends Thread {
    private CountDownLatch comingTag;
    private CountDownLatch waitTag;
    private CountDownLatch waitRunTag;
    private CountDownLatch beingTag;
    private CountDownLatch endTag;

    public MyThread(CountDownLatch comingTag, CountDownLatch waitTag, CountDownLatch waitRunTag, CountDownLatch beingTag, CountDownLatch endTag) {
        super();
        this.comingTag = comingTag;
        this.waitTag = waitTag;
        this.waitRunTag = waitRunTag;
        this.beingTag = beingTag;
        this.endTag = endTag;
    }

    @Override
    public void run() {
        System.out.println("各位运动员正在到达起跑点的路上");
        try {
            /**
             * 各个线程运行使comingTag -1,
             * 然后waitTag 等待
             * 然后waitRunTag - 1
             * 然后beingTag 等待
             * 然后endTag - 1
             */
            Thread.sleep((int) Math.random() * 10000);
            System.out.println(Thread.currentThread().getName() + "到起跑点了");
            comingTag.countDown();
            System.out.println("等待裁判说准备");
            waitTag.await();
            System.out.println("准备起跑");
            Thread.sleep((int) (Math.random() * 10000 + 1000));
            waitRunTag.countDown();
            beingTag.await();
            System.out.println(Thread.currentThread().getName() + " 运动员开跑");
            Thread.sleep((int) (Math.random() * 10000 + 1000));
            endTag.countDown();
            System.out.println(Thread.currentThread().getName() + "运动员到达终点");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        CountDownLatch comingTag = new CountDownLatch(10);
        CountDownLatch waitTag = new CountDownLatch(1);
        CountDownLatch waitRunTag = new CountDownLatch(10);
        CountDownLatch beingTag = new CountDownLatch(1);
        CountDownLatch endTag = new CountDownLatch(10);

        MyThread[] myThreads = new MyThread[10];
        for (int i = 0; i < myThreads.length; i++) {
            myThreads[i] = new MyThread(comingTag, waitTag, waitRunTag, beingTag, endTag);
            myThreads[i].start();
        }
        System.out.println("裁判员在等待选手的到来");
        try {
            /**
             * 与上面的run()方法结合起来看
             * comingTag 等待
             * waitTag -1
             * waitRunTag 等待
             * beingTag -1
             * endTag 等待
             */
            comingTag.await();
            System.out.println("所有运动员到来,裁判巡视五秒");
            Thread.sleep(5000);
            waitTag.countDown();
            System.out.println("各就各位");
            waitRunTag.await();
            Thread.sleep(2000);
            System.out.println("开始跑");
            beingTag.countDown();
            endTag.await();
            System.out.println("Game Over");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


打印结果

各位运动员正在到达起跑点的路上
各位运动员正在到达起跑点的路上
各位运动员正在到达起跑点的路上
各位运动员正在到达起跑点的路上
各位运动员正在到达起跑点的路上
各位运动员正在到达起跑点的路上
各位运动员正在到达起跑点的路上
Thread-2到起跑点了
Thread-5到起跑点了
等待裁判说准备
各位运动员正在到达起跑点的路上
Thread-6到起跑点了
等待裁判说准备
各位运动员正在到达起跑点的路上
裁判员在等待选手的到来
各位运动员正在到达起跑点的路上
Thread-4到起跑点了
等待裁判说准备
Thread-3到起跑点了
等待裁判说准备
等待裁判说准备
Thread-8到起跑点了
等待裁判说准备
Thread-9到起跑点了
等待裁判说准备
Thread-7到起跑点了
等待裁判说准备
Thread-1到起跑点了
等待裁判说准备
Thread-0到起跑点了
等待裁判说准备
所有运动员到来,裁判巡视五秒
各就各位
准备起跑
准备起跑
准备起跑
准备起跑
准备起跑
准备起跑
准备起跑
准备起跑
准备起跑
准备起跑
开始跑
Thread-5 运动员开跑
Thread-1 运动员开跑
Thread-4 运动员开跑
Thread-7 运动员开跑
Thread-3 运动员开跑
Thread-8 运动员开跑
Thread-9 运动员开跑
Thread-6 运动员开跑
Thread-2 运动员开跑
Thread-0 运动员开跑
Thread-1运动员到达终点
Thread-6运动员到达终点
Thread-5运动员到达终点
Thread-7运动员到达终点
Thread-3运动员到达终点
Thread-8运动员到达终点
Thread-0运动员到达终点
Thread-4运动员到达终点
Thread-9运动员到达终点
Thread-2运动员到达终点
Game Over

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
嗨!很高兴回答你关于Java并发编程的问题。请问你想知道什么方面的内容呢?我可以分享一些学习笔记和建议给你。 1. 并发编程基础:了解并发编程的基本概念,如线程、进程、锁、同步等。学习Java中的并发编程模型以及相关的API,如Thread、Runnable、Lock、Condition等。 2. 线程安全性:学习如何保证多线程环境下的数据安全性,了解共享资源的问题以及如何使用同步机制来防止数据竞争和并发问题。 3. 线程间的通信:掌握线程间的通信方式,如使用wait/notify机制、Lock/Condition等来实现线程的协调与通信。 4. 并发容器:学习并发容器的使用,如ConcurrentHashMap、ConcurrentLinkedQueue等。了解它们的实现原理以及在多线程环境下的性能特点。 5. 并发工具类:熟悉Java提供的并发工具类,如CountDownLatch、CyclicBarrier、Semaphore等,它们可以帮助你更方便地实现线程间的协作。 6. 并发编程模式:学习一些常见的并发编程模式,如生产者-消费者模式、读者-写者模式、线程池模式等。了解这些模式的应用场景和实现方式。 7. 性能优化与调试:学习如何分析和调试多线程程序的性能问题,了解一些性能优化的技巧和工具,如使用线程池、减少锁竞争、避免死锁等。 这些只是一些基本的学习笔记和建议,Java并发编程是一个庞大而复杂的领域,需要不断的实践和深入学习才能掌握。希望对你有所帮助!如果你有更具体的问题,欢迎继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值