第二章 CountDownLatch和Semaphone的应用

简介: 第二章 CountDownLatch和Semaphone的应用

前言


Java JUI 之并发编程,CountDownLatch 和 Semaphone 的应用


1、CountDownLatch


CountDownLatch是一个同步工具类,它通过一个计数器来实现的,初始值为线程的数量。每当一个线程完成了自己的任务,计数器的值就相应得减1。当计数器到达0时,表示所有的线程都已执行完毕,然后在等待的线程就可以恢复执行任务。

CountDownLatch(int count):count为计数器的初始值(一般需要多少个线程执行,count就设为几)。


  • CountDownLatch(int count):count为计数器的初始值(一般需要多少个线程执行,count就设为几)。
  • countDown(): 每调用一次计数器值-1,直到count被减为0,代表所有线程全部执行完毕。
  • getCount():获取当前计数器的值。
  • await(): 等待计数器变为0,即等待所有异步线程执行完毕。
  • boolean await(long timeout, TimeUnit unit):
  • 此方法与await()区别:
  • ①此方法至多会等待指定的时间,超时后会自动唤醒,若 timeout 小于等于零,则不会等待
  • ②boolean 类型返回值:若计数器变为零了,则返回 true;若指定的等待时间过去了,则返回 false


1.1、应用场景


某个线程需要在其他n个线程执行完毕后再向下执行

多个线程并行执行同一个任务,提高响应速度

列子:

import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@Slf4j
public class ThreadTest extends  Thread{

    public static void main(String[] args) throws InterruptedException, ExecutionException {

        /*ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 2, 60, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(5), new ThreadPoolExecutor.AbortPolicy());*/

        ExecutorService executorService = Executors.newWorkStealingPool();
        //定义一个计数器
        CountDownLatch countDownLatch = new CountDownLatch(20);
        //把各个地区统计数据放到一个map里面,key:区域    value:销量 、  统计用的时间
        for (int i = 0; i < 20; i++) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    //销量统计的方法
                    countDownLatch.countDown();
                }
            };
            executorService.execute(runnable);
        }
        //等待形成全部执行完成
        countDownLatch.await();

        //把map打印出来
        log.info("end ----");
    }

}


2、Semaphone


一个计数信号量,从概念上将,信号量维护了一个许可集,如有必要,在许可可用前会阻塞每一个acquire(),然后在获取该许可。每个release()添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore只对可用许可的号码进行计数,并采取相应的行动

具体常用的方法有:

方法 说明
acquire() 从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断
release() 释放一个许可,将其返回给信号量

设置许可数量,Semaphore semaphore = new Semaphore(3);

一般acquire()都会抛出异常,release在finally中执行

例子:

汽车抢位

public static void main(String[] args) {
    /**
     * 10辆车  4个停车位的问题
     */
    //初始化信号量
    Semaphore semaphore = new Semaphore(4);

    ExecutorService executorService = Executors.newFixedThreadPool(100);

    for (int i = 0; i < 10; i++) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    //获取许可
                    semaphore.acquire();
                    System.out.println("进入车位.....");
                    TimeUnit.SECONDS.sleep((int) (Math.random() * 10));
                    System.out.println("离开车位.....");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    //释放许可
                    semaphore.release();
                }
            }
        };

        executorService.execute(runnable);

    }

}


3、总结


CountDownLatch 是一个同步辅助类,它可以让一个或多个线程等待其他线程完成操作之后再继续执行。它通过一个计数器来实现,初始化时指定一个计数值,当某些操作完成时可以调用 countDown() 方法来减小计数值,而等待的线程可以调用 await() 方法来阻塞直到计数值为0。


Semaphore 是一个计数信号量,用来控制同时访问特定资源的线程数量。它通过指定许可数来初始化,线程可以通过 acquire() 方法获取许可,执行相应的操作,然后通过 release() 方法释放许可。


CountDownLatch 主要用于一个或多个线程等待其他线程的完成,而 Semaphore 主要用于控制同时访问特定资源的线程数量。它们都是多线程编程中常用的同步工具,可以帮助我们有效地管理线程之间的协调和资源访问。


相关文章
|
3月前
|
消息中间件 RocketMQ
CountDownLatch原理
文章讲述了CountDownLatch的工作原理及其用途: 1. CountDownLatch是一个简单的同步工具,用于等待一组操作完成。 2. 它通过AQS框架实现,利用共享锁模式控制线程的等待与唤醒。 3. 适用于多线程环境下,一个线程需要等待多个其他线程完成各自的任务后再继续执行的场景。
|
6月前
CountDownLatch 实战
CountDownLatch 实战
50 0
|
6月前
|
数据采集 Java API
Java并发基础:CyclicBarrier全面解析!
CyclicBarrier的优点在于实现了线程间的相互等待与协同,确保所有线程在达到预定屏障点后才能继续执行,它支持屏障的重复使用,非常适合多轮次的任务同步,此外,CyclicBarrier还允许在屏障点执行特定操作,为复杂的多线程协作提供了便利。
135 3
Java并发基础:CyclicBarrier全面解析!
|
6月前
并发编程之CountDownLatch和CyclicBarrier的详细解析(带小案例)
并发编程之CountDownLatch和CyclicBarrier的详细解析(带小案例)
85 0
深入理解JUC:第四章:CountDownLatch倒计时器
深入理解JUC:第四章:CountDownLatch倒计时器
深入理解JUC:第四章:CountDownLatch倒计时器
|
安全 Java 测试技术
CountDownLatch原理剖析
CountDownLatch原理剖析
110 0
|
Java
Java多线程-CountDownLatch、Semaphone、CyclicBarrier入门
多线程CountDownLatch、Semaphone、CyclicBarrier讲解
181 1
Java多线程-CountDownLatch、Semaphone、CyclicBarrier入门
|
Java API
CountDownLatch源码硬核解析
CountDownLatch源码硬核解析
150 0
CountDownLatch源码硬核解析