java线程同步CoutDownLatch、CylicBarrier、Semsphore

news/2024/4/18 18:51:09

CountDownLatch

CountDownLatch是Java并发包(java.util.concurrent)中的一种同步工具,它允许一个或多个线程等待其他线程完成任务后再执行。CountDownLatch通常用于在多线程环境下协调任务的执行顺序。

CountDownLatch的基本用法如下:

  1. 创建一个CountDownLatch实例:

import java.util.concurrent.CountDownLatch;public class CountDownLatchExample {public static void main(String[] args) throws InterruptedException {CountDownLatch latch = new CountDownLatch(3); // 初始化CountDownLatch,需要3个线程调用countDown()方法Thread thread1 = new Thread(new Task(latch, "Thread 1"));Thread thread2 = new Thread(new Task(latch, "Thread 2"));Thread thread3 = new Thread(new Task(latch, "Thread 3"));thread1.start();thread2.start();thread3.start();}
}class Task implements Runnable {private final CountDownLatch latch;private final String name;public Task(CountDownLatch latch, String name) {this.latch = latch;this.name = name;}@Overridepublic void run() {try {System.out.println("Task " + name + " is running");Thread.sleep(1000); // 模拟任务执行时间System.out.println("Task " + name + " completed");latch.countDown(); // 当计数器减至0时,所有等待的线程将被唤醒} catch (InterruptedException e) {e.printStackTrace();}}
}

在这个示例中,我们创建了一个名为CountDownLatchExample的类。main()方法中,我们创建了一个CountDownLatch实例,并为3个线程分别分配了任务。然后,我们启动这3个线程。每个线程在完成任务后调用CountDownLatch的countDown()方法,当计数器减至0时,主线程将被唤醒。

CyclicBarrier

CyclicBarrier是Java并发包(java.util.concurrent)中的一种同步工具,它允许一组线程在达到某个共享状态时一起阻塞。CyclicBarrier主要用于协调多个线程之间的顺序执行或同步。

CyclicBarrier的基本用法如下:

  1. 创建一个CyclicBarrier实例:

import java.util.concurrent.CyclicBarrier;public class CyclicBarrierExample {public static void main(String[] args) throws InterruptedException {CyclicBarrier barrier = new CyclicBarrier(3); // 初始化CyclicBarrier,需要3个线程调用await()方法Thread thread1 = new Thread(new Task(barrier, "Thread 1"));Thread thread2 = new Thread(new Task(barrier, "Thread 2"));Thread thread3 = new Thread(new Task(barrier, "Thread 3"));thread1.start();thread2.start();thread3.start();}
}class Task implements Runnable {private final CyclicBarrier barrier;private final String name;public Task(CyclicBarrier barrier, String name) {this.barrier = barrier;this.name = name;}@Overridepublic void run() {try {System.out.println("Task " + name + " is running");Thread.sleep(1000); // 模拟任务执行时间System.out.println("Task " + name + " completed");barrier.await(); // 当所有线程都到达屏障时,主线程将被唤醒} catch (InterruptedException e) {e.printStackTrace();}}
}

在这个示例中,我们创建了一个名为CyclicBarrierExample的类。main()方法中,我们创建了一个CyclicBarrier实例,并为3个线程分别分配了任务。然后,我们启动这3个线程。每个线程在完成任务后调用CyclicBarrier的await()方法,当所有线程都到达屏障时,主线程将被唤醒。

Semaphore

Semaphore是Java并发包(java.util.concurrent)中的一种同步工具,它允许一组线程在达到某个共享状态时进行互斥访问。Semaphore有两个重要类型:

  1. Semaphore:Semaphore是一个计数信号量,用于控制同时访问的线程数量。创建一个Semaphore实例时,可以指定初始值和最大值。当一个线程尝试获取信号量时,如果计数小于最大值,则计数加1;否则,线程将等待直到计数减少到可用值。

  2. CountDownLatch:CountDownLatch也是一个计数信号量,但它允许一个或多个线程在到达某个共享状态后继续执行。创建一个CountDownLatch实例时,可以指定初始值。当一个或多个线程调用countDown()方法时,计数减1。当计数变为0时,所有等待的线程都将被唤醒。

下面是Semaphore的示例代码:


import java.util.concurrent.Semaphore;public class SemaphoreExample {public static void main(String[] args) throws InterruptedException {int initialValue = 5; // 初始化Semaphore,允许5个线程同时访问int maxValue = 10; // 最大允许访问的线程数为10Semaphore semaphore = new Semaphore(initialValue, maxValue); // 创建一个Semaphore实例,初始值为5,最大值为10Thread thread1 = new Thread(new Task(semaphore));Thread thread2 = new Thread(new Task(semaphore));Thread thread3 = new Thread(new Task(semaphore));Thread thread4 = new Thread(new Task(semaphore));thread1.start();thread2.start();thread3.start();thread4.start();}
}class Task implements Runnable {private final Semaphore semaphore;public Task(Semaphore semaphore) {this.semaphore = semaphore;}@Overridepublic void run() {try {semaphore.acquire(); // 尝试获取信号量,如果可用则计数加1,否则等待直到可用System.out.println("Thread " + Thread.currentThread().getName() + " is running");Thread.sleep(1000); // 模拟任务执行时间semaphore.release(); // 释放信号量,计数减1System.out.println("Thread " + Thread.currentThread().getName() + " completed");} catch (InterruptedException e) {e.printStackTrace();}}
}

CoutDownLatch和CylicBarrier区别

CountDownLatch和CyclicBarrier都是Java并发包(java.util.concurrent)中用于协调多个线程之间同步的工具,但它们在实现上有所不同。

  1. CountDownLatch
    CountDownLatch是一个计数信号量,允许一个或多个线程在到达某个共享状态后继续执行。当一个或多个线程调用countDown()方法时,计数减1。当计数变为0时,所有等待的线程都将被唤醒。CountDownLatch通常与Semaphore一起使用,以控制同时访问的资源数量。

示例代码:


import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;public class CountDownLatchExample {public static void main(String[] args) throws InterruptedException {int initialValue = 5; // 初始化CountDownLatch,允许5个线程同时执行countDown()方法int maxValue = 10; // 最大允许执行的线程数为10CountDownLatch countDownLatch = new CountDownLatch(initialValue); // 创建一个CountDownLatch实例,初始值为5for (int i = 0; i < initialValue; i++) {new Thread(new Task(countDownLatch)).start(); // 创建多个线程,每个线程都调用countDown()方法}countDownLatch.await(); // 所有线程执行完countDown()方法后,主线程才会继续执行System.out.println("All threads completed");}
}class Task implements Runnable {private final CountDownLatch countDownLatch;public Task(CountDownLatch countDownLatch) {this.countDownLatch = countDownLatch;}@Overridepublic void run() {try {countDownLatch.countDown(); // 每调用一次countDown()方法,计数减1System.out.println("Thread " + Thread.currentThread().getName() + " is running");Thread.sleep(1000); // 模拟任务执行时间} catch (InterruptedException e) {e.printStackTrace();} finally {countDownLatch.countDown(); // 在finally块中再次调用countDown()方法,确保所有线程都执行完countDown()方法后计数减1}}
}
  1. CyclicBarrier

http://www.ppmy.cn/news/101275.html

相关文章

C++高级语法

文章目录 C高级语法面向对象 -- 类/结构体抽象-具体类型 标准I/O流I/O流I/O缓存区 文件操作头文件的重复包含问题深拷贝和浅拷贝&#xff0c;写时复制面向对象的三大特性面向对象是什么 C高级语法 面向对象 – 类/结构体 C使用class定义一个类&#xff0c;使用struct定义一个…

studio one6免费版下载及配置要求 附精调效果包

提到编曲软件&#xff0c;就不得不说这款水果编曲软件。它对新手和老手都比较友好&#xff0c;是一款较为经典的编曲软件。 这款软件提供了强大而全面的音符、音效编辑器&#xff0c;可以在其中插入各种乐器声音&#xff0c;如果内置乐器无法满足编曲需求&#xff0c;还可以外…

Zookeeper学习---2、客户端API操作、客户端向服务端写数据流程

1、客户端API操作 1.1 IDEA 环境搭建 前提&#xff1a;保证 hadoop102、hadoop103、hadoop104 服务器上 Zookeeper 集群服务端启动。 1、创建一个工程&#xff1a;Zookeeper 2、添加pom文件 <?xml version"1.0" encoding"UTF-8"?> <project …

vue插槽使用总结

什么是插槽解决什么问题插槽的分类默认插槽具名插槽作用域插槽 什么是插槽 插槽就是子组件中的提供给父组件使用的一个占位符&#xff0c;用 表示&#xff0c;父组件可以在这个占位符中填充任何模板代码&#xff0c;如 HTML、组件等&#xff0c;填充的内容会替换子组件的标签。…

【Netty】一行简单的writeAndFlush都做了哪些事(十八)

文章目录 前言一、源码分析1.1 ctx.writeAndFlush 的逻辑1.2 writeAndFlush 源码1.3 ChannelOutBoundBuff 类1.4 addMessage 方法1.5 addFlush 方法1.6 AbstractNioByteChannel 类 总结 前言 回顾Netty系列文章&#xff1a; Netty 概述&#xff08;一&#xff09;Netty 架构设…

Linux——http协议1

目录 URL http协议 http请求 http响应 细节优化 makefile HttpServer.hpp HttpServer.cc Util.hpp

Hack The Box - 关卡Dancing

SMB(全称是Server Message Block)是一个协议名&#xff0c;可用于在计算机间共享文件、打印机、串口等&#xff0c;电脑上的网上邻居就是靠它实现的。 SMB 是一种客户机/服务器、请求/响应协议。通过 SMB 协议&#xff0c;客户端应用程序可以在各种网络环境下读、写服务器上的…

软考A计划-试题模拟含答案解析-卷八

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…

若依源码解析:代码生成ruoyi-generator

文章目录 摘要代码生成器的使用数据库连接配置数据库表设计代码生成器配置修改mybatis别名配置&#xff0c;增加对com.cyl包名的识别修改mybatis的mapper扫描包路径 代码生成代码输出模板配置 代码生成器原理模板引擎&#xff1a;Velocity使用Velocity模板引擎的一般流程模板语…

Java设计模式-解释器模式

简介 设计模式是软件开发中重要的概念之一&#xff0c;它们为我们提供了可重用、灵活和可扩展的解决方案。在Java领域中&#xff0c;解释器模式是一种强大的设计模式&#xff0c;它能够将复杂的问题拆分成简单的表达式&#xff0c;并提供一种灵活的方式来解释和执行这些表达式…

律师使用ChatGPT 进行法律文献检索提交了错误信息;李开复表示,威力强大的大模型将彻底变革人工智能

&#x1f680; 一名律师使用ChatGPT 进行法律文献检索提交了错误信息 近日&#xff0c;一名律师在法庭案件中使用聊天机器人 ChatGPT 进行法律文献检索&#xff0c;结果提交了错误信息&#xff0c; 揭示了人工智能在法律领域的潜在风险&#xff0c;包括误传错误信息。 该事件…

数字化时代,企业面临哪些共同的挑战?

在这种全新的社会、商业环境下&#xff0c;各行各业的企业都开始寻求探索新的商业模式&#xff0c;通过转型适应当前时代的转变&#xff0c;促进业务健康持续的发展。所以数字化成为了企业进行转型的工具&#xff0c;也成为了众多领域内企业对未来的共识。 一、管理挑战 ●经…

Logisim 头歌 偶校验编码设计图解及代码(计算机组成原理)

努力是为了不平庸~ 学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。 急的同学请直接点击目录跳到下方解答处&#xff01;&#xff01; 目录 图解&#xff1a; 代码题解&#xff08;免费&#xff09;&#xff1a; 实…

做外贸算运费的时候需不需要多算一些

看到一个网友在一篇文章下留言说&#xff1a;客户算运费的时候需不需要多算一些 听公司老员工说给客户算运费要多加20% 这样合适吗 我个人感觉有点离谱。 那我们就这个话题&#xff0c;谈一谈运费是否要多加一些呢&#xff1f;为什么要多加一些&#xff1f; 首先&#xff0c;要…

swagger页面 doc.html出不来,swagger-ui/index.html能出来

swagger页面 doc.html出不来&#xff0c;swagger-ui/index.html能出来。前前后后折腾了很久&#xff0c;jar包冲突&#xff0c;jar包版本&#xff0c;添加路径啥的都弄了&#xff0c;就是出不来。 后来全局搜索“doc.html”页面发现能出来的项目能搜到这个页面&#xff1a; 定…

springboot+vue+java旅行旅游景点酒店预订出行订票系统eaog5

线上旅行信息管理系统要求实现以下功能&#xff1a; a.景点管理&#xff0c;展示景点的基础信息&#xff0c;介绍等信息。 b.酒店管理,展示酒店的基础信息&#xff0c;介绍等信息。 c.评价管理&#xff0c;可以查看景点或酒店的相关评价信息&#xff0c;客户消费完&#xff0c;…

实时频谱-3.1实时频谱分析仪测量

RSA 测量类型 泰克RSA 可以在频域、时域、调制域和统计域中工作。 频域测量 基本频域测量是实时 RF 数字荧光显示(DPX)频谱显示测量、频谱显示测量和频谱图显示测量功能。 DPX 频谱 DPX 频谱测量对 RSA 发现其它分析仪漏掉的难检信号的能力至关重要。在所有泰克 RSA 中&am…

《面向对象程序设计》实践任务书

《面向对象程序设计》实践任务书 一、基本要求 &#xff08;1&#xff09;要求利用面向对象的方法以及c编程语言来完成系统的设计&#xff1b; &#xff08;2&#xff09;要求在设计的过程中&#xff0c;建立清晰的类层次&#xff1b; &#xff08;3&#xff09;自行设计文件保…

electron-vue 运行报错 Object.fromEntries is not a function

文章目录 1. 背景2. 解决方案2.1 第一步&#xff1a;安装依赖2.2 第二步&#xff1a;项目中引入 3. 组件详解 1. 背景 最近研究一款桌面端应用的开发框架electron-vue&#xff0c;在按照 electron-vue官方文档 操作之后操作如下&#xff0c;Object.fromEntries is not a funct…

C语言编程 7-12 日期格式化

世界上不同国家有不同的写日期的习惯。比如美国人习惯写成“月-日-年”&#xff0c;而中国人习惯写成“年-月-日”。下面请你写个程序&#xff0c;自动把读入的美国格式的日期改写成中国习惯的日期。 输入格式&#xff1a; 输入在一行中按照“mm-dd-yyyy”的格式给出月、日、年…