Java并发编程 之CountDownLatch、CyclicBarrier、Semaphore同步辅助类

详解Java多线程编程中CountDownLatch阻塞线程的方法 在Java中和ReadWriteLock.ReadLock一样,CountDownLatch的本质也是一个"共享锁",这里我们就来详解Java多线程编程中CountDownLatch阻塞线程的方法: 立即下载

CountDownLatch(发射倒计时)

教室晚自习放学关灯,需要等所有学生上完自习离开教室后才能关灯;主线程:关灯,子线程:学生上完自习离开教室。关灯之后不能重新打开后再关闭了,是一次性的。

主线程阻塞直到一组子线程全部执行完后才被唤醒。
CountDownLatch可以理解为一个计数器,直到计数器为0了,等待的线程才执行。
CountDownLatch主要有两个方法,当一个或多个线程调用await方法时,调用线程会被阻塞。其他线程调用countDown方法计数器减1(调用countDown方法时线程不会阻塞),当计数器的值变为0,因调用await方法被阻塞的线程会被唤醒,继续执行。

构造方法:

// count 就是需要等待的线程数量
public CountDownLatch(int count)

重要方法:

// 调用此方法的线程会被阻塞,直到 CountDownLatch 的 count 为 0
public void await() throws InterruptedException 

// 和上面的 await() 作用基本一致,只是可以设置一个最长等待时间
public boolean await(long timeout, TimeUnit unit) throws InterruptedException

// 会将 count 减 1
public void countDown() 

使用场景:
场景1:
主线程等待其他线程完成各自任务后再开始执行自己的任务。
代码实现:

public class CountDownLatchDemo {

    static class TaskThread extends Thread {
        CountDownLatch latch;
        public TaskThread(CountDownLatch latch) {
            this.latch = latch;
        }
        @Override
        public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                System.out.println(getName() + " Task is Done ");
                latch.countDown();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException{
        int threadNum = 10;
        CountDownLatch latch = new CountDownLatch(threadNum);
        for(int i = 0; i < threadNum; i++) {
            new TaskThread(latch).start();
        }
        System.out.println("Task Start!");
        // 等待CountDownLatch计数为0后执行
        latch.await();
        System.out.println("All Task is Done!");
    }
}

代码解释:

  • 设置 CountDownLatch 的等待线程数为 10
  • 开启 10 个线程,每个线程都会睡眠 1 秒,睡眠结束后就会调用 CountDownLatch 的 countDown() 方法
  • 主线程调用 CountDownLatch 的 await() 方法,所以会开始阻塞,直到 CountDownLatch 的 count 为 0 才继续执行

打印结果:

Task Start!
Thread-1 Task is Done
Thread-5 Task is Done
Thread-8 Task is Done
Thread-9 Task is Done
Thread-2 Task is Done
Thread-7 Task is Done
Thread-6 Task is Done
Thread-4 Task is Done
Thread-3 Task is Done
Thread-0 Task is Done
All Task is Done!

场景2:
同时启动多个线程。
如果想同时启动多个线程,实现最大的并行性,就可以使用 CountDownLatch。
代码实现一:

CountDownLatch countDownLatch = new CountDownLatch(1);
ExecutorService executorService = Executors.newFixedThreadPool(5);
List<Future<?>> futures = new ArrayList<>();
for(int i=0; i<5; i++){
    Future<?> future = executorService.submit(() -> {
        try {
            countDownLatch.await();
            Thread.sleep(3000L);
            System.out.println("Thread:" + Thread.currentThread().getName() + ",time: " + System.currentTimeMillis());
        } catch (Exception e) {
            e.printStackTrace();
        }
    });
    futures.add(future);
}
countDownLatch.countDown();
executorService.shutdown();
for (int i=0; i<futures.size(); i++){
    futures.get(i).get();
}
System.out.println("end...");

打印结果:

Thread:pool-1-thread-1,time: 1564034719458
Thread:pool-1-thread-2,time: 1564034719458
Thread:pool-1-thread-3,time: 1564034719458
Thread:pool-1-thread-5,time: 1564034719458
Thread:pool-1-thread-4,time: 1564034719458

Process finished with exit code 0

代码实现二:

public class CountDownLatchDemo {
    static class TaskThread extends Thread {
        CountDownLatch latch;
        public TaskThread(CountDownLatch latch) {
            this.latch = latch;
        }
        @Override
        public void run() {
            try {
                latch.await();
                System.out.println(getName() + " start " + System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    } 
    public static void main(String[] args) throws Exception{
        int threadNum = 10;
        CountDownLatch latch = new CountDownLatch(1);
        for(int i = 0; i < threadNum; i++) {
            TaskThread task = new TaskThread(latch);
            task.start();
        }
        Thread.sleep(1000);
        latch.countDown();
    }
}

代码解释:

  • 设置 CountDownLatch 等待线程数为 1
  • 开启 10 个线程,每个线程都会调用 CountDownLatch 的 await() 方法,这样每个线程都会被阻塞
  • 主线程休眠 1 秒后,调用 CountDownLatch 的 countDown() 方法,调用后就会唤醒所有等待的线程,所有等待的线程就会同时执行

打印结果:

Thread-2 start 1564035004459
Thread-4 start 1564035004459
Thread-0 start 1564035004459
Thread-7 start 1564035004459
Thread-5 start 1564035004459
Thread-3 start 1564035004459
Thread-1 start 1564035004459
Thread-6 start 1564035004459
Thread-9 start 1564035004459
Thread-8 start 1564035004459

Process finished with exit code 0

秦灭六国

import java.util.concurrent.CountDownLatch;

public class CountDownLatchDemo {

    public static void main(String[] args) throws Exception {
        CountDownLatch countDownLatch = new CountDownLatch(5);

        for (int i = 1; i <= 5; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "\t" + "国,灭亡");
                countDownLatch.countDown();
            }, CountryEnum.forEach(i).getName()).start();
        }

        countDownLatch.await();
        System.out.println("秦统一");
    }
}

// 枚举可以作为简单版本的数据库
enum CountryEnum {
    ONE(1, "齐"), TWO(2, "楚"), THREE(3, "燕"),
    FOUR(4, "赵"), FIVE(5, "魏"), SIX(6, "韩");

    CountryEnum(Integer code, String name) {
        this.code = code;
        this.name = name;
    }

    private Integer code;
    private String name;

    public static CountryEnum forEach(int index) {
        CountryEnum[] countryEnums = CountryEnum.values();
        for (CountryEnum countryEnum : countryEnums) {
            if (index == countryEnum.getCode()) {
                return countryEnum;
            }
        }
        return null;
    }

    public Integer getCode() {
        return code;
    }

    public String getName() {
        return name;
    }
}

批处理

public static <T> void dispose(List<T> taskList, Consumer<? super T> consumer, Executor executor) throws InterruptedException {
    if (taskList == null || taskList.size() == 0) {
        return;
    }
    Objects.nonNull(consumer);
    CountDownLatch countDownLatch = new CountDownLatch(taskList.size());
    for (T item : taskList) {
        executor.execute(() -> {
            try {
                consumer.accept(item);
            } finally {
                countDownLatch.countDown();
            }
        });
    }
    countDownLatch.await();
}

ExecutorService executorService = Executors.newFixedThreadPool(10);
dispose(taskList, param -> {
    System.out.println(param);
    try {
        TimeUnit.SECONDS.sleep(1);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}, executorService);
executorService.shutdown();

CyclicBarrier(循环栅栏)

集齐七颗龙珠才能召唤神龙。

简介

中文意思是循环栅栏。
作用:让所有线程都等待完成后才会继续下一步行动。
举个例子:就像生活中我们会约朋友们到某个餐厅一起吃饭,有些朋友可能会早到,有些朋友可能会晚到,但是这个餐厅规定必须等到所有人到齐之后才会让我们进去。这里的朋友们就是各个线程,餐厅就是 CyclicBarrier。

CyclicBarrier可以使一定数量的线程反复地在栅栏位置处汇集。当线程到达栅栏位置时将调用await方法,这个方法将阻塞直到所有线程都到达栅栏位置。如果所有线程都到达栅栏位置,那么栅栏将打开,此时所有的线程都将被释放,而栅栏将被重置以便下次使用。

CyclicBarrier使用

构造方法:

public CyclicBarrier(int parties) {
    this(parties, null);
}
 
public CyclicBarrier(int parties, Runnable barrierAction) {
    if (parties <= 0) throw new IllegalArgumentException();
    this.parties = parties;
    this.count = parties;
    this.barrierCommand = barrierAction;
}
  • parties 参数表示屏障拦截的线程数量,每个线程使用await()方法告诉CyclicBarrier我已经到达了屏障,然后当前线程被阻塞。
  • 第二个构造方法有一个 Runnable 参数,这个参数的意思是最后一个到达线程要做的任务。

await方法:

public int await() throws InterruptedException, BrokenBarrierException {
    try {
        // 不超时等待
        return dowait(false, 0L);
    } catch (TimeoutException toe) {
        throw new Error(toe); // cannot happen
    }
}

public int await(long timeout, TimeUnit unit)
    throws InterruptedException,
            BrokenBarrierException,
            TimeoutException {
    return dowait(true, unit.toNanos(timeout));
}
  • 线程调用 await() 表示自己已经到达栅栏,然后当前线程被阻塞,直到parties个参与线程调用了await方法。
  • BrokenBarrierException 表示栅栏已经被破坏,破坏的原因可能是其中一个线程 await() 时被中断或者超时

CyclicBarrier示例

public class CyclicBarrierDemo {
    // 集龙珠
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(7, () -> {
            System.out.println("龙珠收集完成");
        });
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 1; i <= 7; i++) {
            int finalI = i;
            executorService.submit(() -> {
                try {
                    TimeUnit.SECONDS.sleep((long) new Random().nextInt(5) + 1);
                    System.out.println(Thread.currentThread().getName() + "\t收集到龙珠" + finalI);
                    cyclicBarrier.await();
                    TimeUnit.SECONDS.sleep((long) new Random().nextInt(5) + 1);
                    System.out.println(Thread.currentThread().getName() + "\t收集到龙珠" + finalI);
                    cyclicBarrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, "Thread-" + i);

        }
        executorService.shutdown();
    }
}

在这里插入图片描述
所有的工作线程都运行await()方法之后都到达了栅栏位置,然后执行到达后的任务。
从打印结果可以看出,所有线程会等待全部线程到达栅栏之后才会继续执行,并且最后到达的线程会完成 Runnable 的任务。

CyclicBarrier使用场景

可以用于多线程计算数据,最后合并计算结果的场景。

Semaphore(信号量)

单机限流,控制线程的并发数。
抢车位。
简介:
Semaphore 主要用于控制当前活动线程的数目,每个线程都需要通过acquire()方法获取许可,使用release()释放许可。当活动线程数目等于最大许可后,那么在调用acquire()方法后,线程会进入等待队列,等待已获取许可的线程释放许可。

定义:

 // 参数permits表示许可数目,即同时可以允许多少线程进行访问
public Semaphore(int permits) {         
    sync = new NonfairSync(permits);
}
// 这个多了一个参数fair表示是否是公平的,即等待时间越久的越先获取许可
public Semaphore(int permits, boolean fair) {    
    sync = (fair)? new FairSync(permits) : new NonfairSync(permits);
}

几个重要方法:

// 获取一个许可
public void acquire() throws InterruptedException { }  
// 获取permits个许可   
public void acquire(int permits) throws InterruptedException { }  
// 释放一个许可 
public void release() { }   
// 释放permits个许可       
public void release(int permits) { }    

acquire()用来获取一个许可,若无许可能够获得,则会一直等待,直到获得许可。
release()用来释放许可。注意,在释放许可之前,必须先获获得许可。
这4个方法都会被阻塞,如果想立即得到执行结果,可以使用下面几个方法:

// 尝试获取一个许可,若获取成功,则立即返回true,若获取失败,则立即返回false
public boolean tryAcquire() { }; 
// 尝试获取一个许可,若在指定的时间内获取成功,则立即返回true,否则则立即返回false
public boolean tryAcquire(long timeout, TimeUnit unit) throws InterruptedException { };  
// 尝试获取permits个许可,若获取成功,则立即返回true,若获取失败,则立即返回false
public boolean tryAcquire(int permits) { }; 
// 尝试获取permits个许可,若在指定的时间内获取成功,则立即返回true,否则则立即返回false
public boolean tryAcquire(int permits, long timeout, TimeUnit unit) throws InterruptedException { }; 

限流使用案例:

public class SemaphoreDemo {

    // 请求总数
    public static int clientTotal = 10;
    // 同时并发执行的线程数
    public static int threadTotal = 5;
    // 已执行线程的数量
    public static int count = 0;

    public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newCachedThreadPool();
        // 信号量,此处用于控制并发的线程数
        final Semaphore semaphore = new Semaphore(threadTotal);
        // 闭锁,可实现计数器递减
        final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
        for (int i = 0; i < clientTotal; i++) {
            executorService.execute(() -> {
                try {
                    // 执行此方法用于获取执行许可,当总计未释放的许可数不超过5时,允许通行,否则线程阻塞等待,直到获取到许可。
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+":start");
                    add();
                    System.out.println(Thread.currentThread().getName()+":end");
                    // 释放许可
                    semaphore.release();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                // 闭锁减一
                countDownLatch.countDown();
            });
        }
        countDownLatch.await();// 线程阻塞,直到闭锁值为0时,阻塞才释放,继续往下执行
        executorService.shutdown();
        System.out.println("执行的总数:" + count);
        return;
    }

    // 业务逻辑
    private static void add() throws InterruptedException {
        count++;
        Random random = new Random();
        int i = random.nextInt(3) + 1;
        Thread.sleep(i * 1000);
    }
}

打印结果: 发现总是只有5个线程在执行中,当其中一个线程执行完并释放许可后,就会唤醒一个等待的线程执行。

pool-1-thread-1:start
pool-1-thread-2:start
pool-1-thread-3:start
pool-1-thread-4:start
pool-1-thread-5:start
pool-1-thread-2:end
pool-1-thread-6:start
pool-1-thread-4:end
pool-1-thread-7:start
pool-1-thread-1:end
pool-1-thread-8:start
pool-1-thread-3:end
pool-1-thread-9:start
pool-1-thread-5:end
pool-1-thread-7:end
pool-1-thread-10:start
pool-1-thread-8:end
pool-1-thread-6:end
pool-1-thread-9:end
pool-1-thread-10:end
执行的总数:10

Process finished with exit code 0

抢车位案例

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

public class SemaphoreDemo {

    public static void main(String[] args) {
        // 模拟3个停车位
        Semaphore semaphore = new Semaphore(3);
        // 模拟6部汽车
        for (int i = 1; i <= 6; i++) {
            new Thread(() -> {
                try {
                    // 抢车位,如果没有车位会阻塞直到抢到车位才被唤醒
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + "\t抢到车位");
                    int time = (int) (Math.random() * 10 + 1);
                    TimeUnit.SECONDS.sleep(time);
                    System.out.println(Thread.currentThread().getName() + "\t停" + time + "秒离开车位,空车一个车位");
                } catch (InterruptedException e) {

                } finally {
                    // 空出车位
                    semaphore.release();
                }
            }, "Thread-" + String.valueOf(i)).start();
        }
    }
}

执行结果:
在这里插入图片描述

三个同步辅助类总结

  • CountDownLatch和CyclicBarrier都能够实现线程之间的等待,只不过它们侧重点不同:
    CountDownLatch一般用于某个线程A等待若干个其他线程执行完任务之后,它才执行;
    而CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;
    另外,CountDownLatch是不能够重用的,而CyclicBarrier是可以重用的。

CountDownLatch是减法,减到0唤醒。
CyclicBarrier是加法,加到一定数量唤醒。

  • Semaphore其实和锁有点类似,它一般用于控制对某组资源的访问权限。比如:限流。

参考:
Java并发编程之CyclicBarrier详解

altium room 布局_ALtium 16相同重复模块PCB布局,复制布局走线 自己做了实际工程以后发现PCB器件名字后缀太长了,所以文章最后写了一下后缀的调整方法。第一种方法:1、建立子原理图如下,文件名CANM 2、之后新建一个顶层文件,文件名TOP,之后design—create sheet symbol form sheet or hdl。选择CANM,并放置到TOP中,如下 3、由于我们要多次调用CANM所以使用repeat命令修改如下: 4、之后根据自己的定义,连... 阅读详情

相关推荐

ATAC-seq数据分析流程

Outline0. ATAC-seq原理0.1 染色体结构0.2 原理0.3 结果0.4 意义1. ATAC-seq数据分析流程1.1 上游分析(1)序列质控和比对(2)序列筛选1.2 下游分析1.3 进阶分析 0. ATAC-seq原理 0.1 染色体结构 0.2 原理 0.3 结果 0.4 意义 1. ATAC-seq数据分析流程 1.1 上游分析 (1)序列质控和比对 fastqc trim_golare bowtie2 mapping时要加上参数 --very-sensitive -X 2000

weixin_57830892的博客 1万+

Java浅谈CountDownLatch的用法

await() 方法是用来阻塞线程的,等待倒计锁被减到0的时候,才会唤醒该方法继续执行。也可以设置等待超时时间,如 countDownLatch.await(30, TimeUnit.SECONDS),设置超时时间则需要判断等待结果,true等待未超时、false等待已超时。countDown() 方法是用来执行线程计数器-1的,也就是多线程运行完之后,都调用此方法将计数器变成0,最后调用await()方法唤醒阻塞的位置,继续执行。1、countDown() 是用来执行倒计锁 -1。

hkl_Forever的博客 3377

grpc安装与简单demo测试

grpc安装: 由于工作需要,最近在学google的rpc开源框架;由于本人菜鸟一枚,而且是从Windows开发转到Linux;由于之前版本控制使用的是svn,没有使用过git,所以从GitHub上下载代码是通过浏览器下载zip格式的压缩文件,折腾了好几天了,发现了各种坑,各种缺少库,各种不知道怎么把这个库给装机器上。对于一个不熟悉Linux的人来说,这个体验简直糟糕透了。没办法了又在机器上装了...

old__captain的博客 4833

【Java基础】线程同步类 CountDownLatch

CountDownLatch是JDK提供的一个同步工具,它可以让一个或多个线程等待,一直等到其他线程中执行完成一组操作。

fumeidonga的博客 4108

MacOS Intel芯片实战:Docker Compose一键部署Dify全流程解析

本文详细解析了在搭载Intel芯片的MacOS系统上,使用Docker Compose一键部署开源LLM应用开发平台Dify的全流程。内容涵盖环境准备、Docker配置与镜像加速、代码拉取与配置初始化、服务启动与问题排查,以及访问验证与初步探索,旨在帮助开发者快速在本地搭建私有化AI应用开发环境。

ik678901234的博客 619

Python开发者必看:5分钟搞定Gemini API的3种调用方式(含代码示例)

本文为Python开发者详细介绍了三种高效调用Gemini API的核心方式:基础同步调用、流式调用和聊天模式,并涵盖多模态应用等高级特性。通过清晰的代码示例和实战场景分析,帮助开发者快速掌握Gemini API的集成与优化,提升AI应用开发效率。

g8f9d0s1a2的博客 1122

countDownLatch.await()与thread.join()区别

在编写多线程的工作中,有个常见的问题:主线程(main) 启动好几个子线程(task)来完成并发任务,主线程要等待所有的子线程完成之后才继续执行main的其它任务。 默认主线程退出时其它子线程不会停,如果想让main退出时其它子线程终止,可以用subThread.setDaemon(true) 设置子线程为“守护线程”。 如果要在主线程等待所有子线程完成后,还要执行其它操作(比如:结果合并)....

u012501054的博客 1万+

LightGBM参数调优实战:从基础到高级技巧

本文深入探讨了LightGBM参数调优的实战技巧。文章从理解其Leaf-wise生长策略的核心逻辑出发,系统性地介绍了分层调参策略:首先调整控制模型结构的参数(如num_leaves),其次优化学习能力参数(如learning_rate),最后通过正则化与随机化参数提升泛化能力。文中还提供了从建立基线到最终微调的完整实战流程与高级避坑指南,帮助读者高效提升模型性能。

i8j9k0l1的博客 262

Java并发编程 之 阻塞队列和CountDownLatch

前几天看到一个面试题目:有一个长度为2000的字符串,开三个线程去判断字符串中”u51”的个数。 当时看到这个题目的时候,对并发编程是没有什么经验的,在实际项目多线程的应用也只有一两次。最近在恶补《Java并发编程的艺术》,对这个题目就有了解题的思路了。在这里记录一下对该题的解法和思路。一开始的时候,我能确定的是对“u51”个数相加是需要做同步处理,主要是如何去用三个线程去遍历这个字符串呢。需要保证索

没有进步就是退步 1019

【单片机】STM32F103C8T6 最小系统板原理图

STM32F103C8T6是一款基于ARM Cortex-M3内核的32位微控制器,由STMicroelectronics(ST)公司生产。它是STMicroelectronics的STM32系列微控制器中的一员,被广泛应用于嵌入式系统和电子设备中。LQFP48封装(Low-profile Quad Flat Package,48引脚)SRAM(静态随机访问存储器):20 KB。支持JTAG调试和编程接口(可选)多个通用输入/输出口(GPIO)USB接口(用于USB设备模式)内置调试和编程接口(SWD)

q742971636的博客 6万+

从一只龙虾到一支团队:OpenClaw 单 Bot 多 Agent 配置实践

单 Bot 多 Agent只有一个对外的聊天入口(飞书 Bot)内部有多个独立的 AI Agent,各司其职主 Agent(总指挥)负责接收任务并分配给子 Agent子 Agent 完成任务后将结果返回给主 Agent角色Agent ID职责使用场景🎯 总指挥main-agent统筹协调,任务分发接收所有用户请求✍️ 笔杆子内容创作公众号、博客、小红书🔬 参谋canmou深度研究竞品分析、市场调研📋 运营官operations运营管理邮件、日历、社交媒体。

Maynor的博客 1081

Java并发编程的4个同步辅助类(CountDownLatch、CyclicBarrier、Semaphore、Phaser)

Java并发编程的4个同步辅助类(CountDownLatch、CyclicBarrier、Semaphore、Phaser)   我在《JDK1.5引入的concurrent包》中,曾经介绍过CountDownLatch、CyclicBarrier两个类,还给出了CountDownLatch的演示案例。这里再系统总结下Java并发编程中的4个类C...

李章勇的博客 650

python爬虫案例——腾讯网新闻标题(异步加载网站数据抓取,post请求)(6)

本篇案例主要讲解异步加载网站如何分析网页接口,以及如何观察post请求URL的参数,网站数据并不难抓取,主要是将要抓取的数据接口分析清楚,才能根据需求编写想要的代码。

@优快云盲敲代码的阿豪的博客 946

JUC多线程:辅助类CountDownLatch、CyclicBarrier、Semaphore实战指南(附保姆级代码)

在Java并发编程的世界里,有三个如同"交通信号灯"般重要的工具类:🚦(倒计时门闩):像运动会起跑前的倒计时🚧(循环栅栏):像组团旅游等人齐发车🚥Semaphore(信号量):像停车场空位显示牌本文将用最接地气的比喻+真实代码案例,带你轻松征服这三个并发利器!工具类核心思想典型应用场景重要特性减法计数器主线程等待多个子线程准备一次性、不可重置加法计数器多线程互相等待触发统一行动可循环使用、支持回调函数Semaphore资源许可证管理限流、数据库连接池控制。

2201_75525624的博客 1050

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

Java并发学习(3)一5种同步辅助类

前言 线程之前通常需要进一步的协调工作,来完成相应比较复杂的并发任务,使用wait/notify等方法都是底层实现。现在我们需要的更为抽象满足具体实际业务的一些方法,这时候我们就会用到相应的5种同步辅助类。 CountDownLatch:它允许一个或多个线程一直等待,直到其他线程执行完后再执行。利用它可以实现类似于计数器的功能。 Semaphore:信号量,如果学过操作系统中PV...

J.Jian博客 770

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

Java并发编程的4个同步辅助类

Java并发编程的4个同步辅助类(CountDownLatch、CyclicBarrier、Semphore、Phaser) @https://www.cnblogs.com/lizhangyong/p/8906774.html 转载于:https://www.cnblogs.com/xingzc/p/9854668.html...

weixin_30384217的博客 97

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

java多线程九: 同步辅助类(Semphore、CountDownLatch、CyclicBarrier、Phaser)

线程同步辅助类,主要学习两点: 1、上述几种同步辅助类的作用以及常用的方法 2、适用场景,如果有适当的场景可以用到,那无疑是最好的 semaphore(seməˌfôr) 含义 信号量就是可以声明多把锁(包括一把锁:此时为互斥信号量)。 举个例子:一个房间如果只能容纳5个人,多出来的人必须在门外面等着。如何去做呢?一个解决办法就是:房间外面挂着五把钥匙,每进去一个人就取走一把钥匙,没有钥匙的不能进入该房间而是在外面等待。每出来一个人就把钥匙放回原处以方便别人再次进入。 常用方法 acqu

zhaofuqiangmycomm的博客 331

java并发之同步辅助类(Semphore、CountDownLatch、CyclicBarrier、Phaser、Exchanger)

1、Semphore字面翻译的意思是(信号量)。正常的锁来自(concurrent.lock或内建的synchronized锁),在任何时刻都只允许一个任务访问同一资源,而技术信号量允许n个任务同时访问这个资源。你还可以就信号量看成是在向外分发资源的"许可证",尽管实际上没有用到人任何的许可证对象。信号量就是允许声明多把锁(含一把锁,此时为互斥信号量)。实现原理:Semaphore是信号量,用于管...

an341221的专栏 452

Java中的5种同步辅助类

原文地址译者:何一昕 校对:方腾飞 概述 当你使用synchronized关键字的时候,是通过互斥器来保障线程安全以及对共享资源的同步访问。线程间也经常需要更进一步的协调执行,来完成复杂的并发任务,比如wait/notify模式就是一种在多线程环境下的协调执行机制。 通过API来获取和释放锁(使用互斥器)或者调用wait/notify等方法都是底层调用...

weixin_34258782的博客 90

Concurrent In Java 6 分享,第四部分 同步辅助类介绍

第一部分 集合 http://jimichan.iteye.com/blog/951948   第二部分 线程池 http://jimichan.iteye.com/blog/951950   第三部分 锁 http://jimichan.iteye.com/blog/951954   第四部分 同步辅助类 http://jimichan.iteye.com/blo...

223

CountDownLatch CyclicBarrier Semaphore 比较

document CountDownLatch A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes. CyclicBarrier A synchronization ...

weixin_34240657的博客 81

Java多线程(八)之Semaphore、CountDownLatch、CyclicBarrier、Exchanger

一、引言 Semaphore               :一个计数信号量 CountDownLatch          :一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。  CyclicBarrier           :一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点     Exchanger

Vern的专栏 8775

线程同步辅助类

线程同步辅助类信号量(Semaphore):是一种计数器,用来保护一个或者多个共享资源的访问。它是并发编程的一种基础攻击,大多数编程语言都提供了这个机制。CountDownLatch:是java语言提供的同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许线程一直等待。CyclicBarrier:是java语言提供的同步辅助类,它允许多个线程在某个集合点处进行相互等待。Phaser:是jav...

weixin_30555753的博客 90

Java并发工具箱:CountDownLatch、CyclicBarrier、Semaphore、Exchanger的神秘力量!

当计数器的值达到构造函数中指定的值时,所有等待的线程会被唤醒,并且可以执行栅栏操作。之后,计数器会重置,等待的线程可以再次等待。是一个同步辅助类,它允许一个或多个线程等待直到在其他线程中执行的一组操作完成。它就像一个倒计时器,等待计数到达零,然后释放所有等待的线程。方法时,如果计数器的值大于零,计数器的值会减一,线程可以继续执行。当计数器的值减到零时,所有等待的线程都会被唤醒。方法时,计数器的值会增加,如果有线程在等待队列中,它们会被唤醒。方法时,两个线程的数据会被交换,并且两个线程都会被唤醒。

赵KK的博客 881

Java面试题:解释CountDownLatch, CyclicBarrier和Semaphore在并发编程中的使用

是 Java 提供的同步辅助类,它们用于控制线程之间的协调。这些同步辅助工具在多线程编程中非常有用,它们可以帮助开发者实现复杂的线程协调和控制逻辑。

杰哥在此的专栏 848
上一篇: Java并发编程 之SpringBoot线程池异步开发
下一篇: Spring原理解析 之BeanDefinition
yyangqqian
博客等级 码龄15年 406粉丝 406原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值