线程基础知识16-线程相关类CyclicBarrier、Semaphore、Exchanger
1 CyclicBarrier
1.1 作用
从字面上的意思可以知道,这个类的中文意思是“循环栅栏”。大概的意思就是一个可循环利用的屏障。
它的作用就是会让所有线程都等待完成后才会继续下一步行动
1.2 示例
//等待指定数量的线程await之后,执行一个runnable。并且await的线程继续执行await后面的代码。
// 如果达不到这个数量,会一直阻塞
private static void m1() {
CyclicBarrier c = new CyclicBarrier(5,()->System.out.println(Thread.currentThread().getName()+"发车"));
for (int i = 0;i < 22;i++){
new Thread(()->{
try { c.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); }
System.out.println(Thread.currentThread().getName());
},"线程" + i).start();
} System.out.println("aaa");
}
1.3 执行结果
上面代码创建一个CyclicBarrier ,设定的是5个线程到达后,才可以执行创建CyclicBarrier 传入的runnable,然后5个线程继续执行
由于是每5个线程才能一期继续执行,而循环共创建22个线程,所以会有两个线程一直阻塞无法向下执行
线程6发车
线程6
线程4发车
线程4
aaa
线程0
线程1
线程2
线程17发车
线程3
线程10
线程9
线程5
线程20
线程7
线程16
线程8
线程17
线程12
线程15发车
线程15
线程18
线程19
线程21
线程14
2 Semaphore
2.1 作用
限制同时执行的线程数(限流)
2.2 示例
private static void m3() {
Semaphore sp = new Semaphore(3);//允许最多三个线程同时请求执行
for (int i = 0;i < 20;i++){
new Thread(()->{
try {
sp.acquire(); //请求执行
System.out.println(Thread.currentThread().getName());
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + "继续执行");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
sp.release(); //释放
}
},"线程" + i).start();
}
}
2.3 执行结果
发现同时执行的线程最多3个
线程0
线程2
线程1
线程1继续执行
线程0继续执行
线程2继续执行
线程3
线程4
线程5
线程5继续执行
线程3继续执行
线程4继续执行
线程7
线程6
线程9
线程6继续执行
线程7继续执行
线程9继续执行
线程10
线程8
线程11
线程11继续执行
线程10继续执行
线程8继续执行
线程13
线程12
线程14
线程12继续执行
线程14继续执行
线程13继续执行
线程16
线程15
线程17
线程16继续执行
线程17继续执行
线程15继续执行
线程18
线程19
线程19继续执行
线程18继续执行
3 Exchanger
3.1 作用
用于两个线程交换数据
3.2 示例
private static void m4() {
Exchanger<String> ex = new Exchanger(); //用于两个线程交换数据
new Thread(()->{
try {
String exchange = ex.exchange("111"); //调用exchange时会阻塞,等待另一个线程调用exchange方法,交换数据后,两个线程继续执行
System.out.println(Thread.currentThread().getName() + ":" + exchange);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"线程1").start();
new Thread(()->{
try {
Thread.sleep(1000);
String exchange = ex.exchange("222");
System.out.println(Thread.currentThread().getName() + ":" + exchange);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"线程2").start();
}
3.3 执行结果
发现两个线程交换了数据,且调用exchange方法会导致阻塞,直到另一个线程也调用exchange方法,完成数据交换,线程才能继续执行
线程1:222
线程2:111
线程基础知识16-线程相关类CyclicBarrier、Semaphore、Exchanger的更多相关文章
- JAVA核心技术I---JAVA基础知识(格式化相关类)
一:格式化相关类 (一)java.text包java.text.Format的子类 –NumberFormat:数字格式化,抽象类 DecimalFormat –MessageFormat:字符串格式 ...
- java线程基础知识----java线程模型
转载自http://www.cnblogs.com/nexiyi/p/java_memory_model_and_thread.html 1. 概述 多任务和高并发是衡量一台计算机处理器的能力重要指标 ...
- Windows核心编程 第六章 线程基础知识 (上)
第6章 线程的基础知识 理解线程是非常关键的,因为每个进程至少需要一个线程.本章将更加详细地介绍线程的知识.尤其是要讲述进程与线程之间存在多大的差别,它们各自具有什么作用.还要介绍系统如何使用线程内核 ...
- C#基础知识回顾--线程传参
C#基础知识回顾--线程传参 在不传递参数情况下,一般大家都使用ThreadStart代理来连接执行函数,ThreadStart委托接收的函数不能有参数, 也不能有返回值.如果希望传递参数给执行函数, ...
- 线程基础知识01-Thread类,Runnable接口
常见面试题:创建一个线程的常用方法有哪些?Thread创建线程和Runnable创建线程有什么区别? 答案通常集中在,继承类和实现接口的差别上面: 如果深入问一些问题:1.要执行的任务写在run()方 ...
- Java__线程---基础知识全面实战---坦克大战系列为例
今天想将自己去年自己编写的坦克大战的代码与大家分享一下,主要面向学习过java但对java运用并不是很熟悉的同学,该编程代码基本上涉及了java基础知识的各个方面,大家可以通过练习该程序对自己的jav ...
- java线程基础知识----线程基础知识
不知道从什么时候开始,学习知识变成了一个短期记忆的过程,总是容易忘记自己当初学懂的知识(fuck!),不知道是自己没有经常使用还是当初理解的不够深入.今天准备再对java的线程进行一下系统的学习,希望 ...
- Java并发之线程管理(线程基础知识)
因为书中涵盖的知识点比较全,所以就以书中的目录来学习和记录.当然,学习书中知识的时候自己的思考和实践是最重要的.说到线程,脑子里大概知道是个什么东西,但很多东西都还是懵懵懂懂,这是最可怕的.所以想着细 ...
- Java线程基础知识(状态、共享与协作)
1.基础概念 CPU核心数和线程数的关系 核心数:线程数=1:1 ;使用了超线程技术后---> 1:2 CPU时间片轮转机制 又称RR调度,会导致上下文切换 什么是进程和线程 进程:程序运行资源 ...
- java线程基础知识----线程与锁
我们上一章已经谈到java线程的基础知识,我们学习了Thread的基础知识,今天我们开始学习java线程和锁. 1. 首先我们应该了解一下Object类的一些性质以其方法,首先我们知道Object类的 ...
随机推荐
- 第一章 计算机和C++简介
1.1 简介 C++是一种强大的计算机面向对象编程的程序设计语言,它是制造软件的一种编程语言,适合程序员和刚接触编程的技术人员.当今智能手机销量爆炸式增长给移动应用程序的开发带来了很多机会,而C++就 ...
- 使用CRD扩展Kubernetes API
本文是如何创建 CRD 来扩展 Kubernetes API 的教程.CRD 是用来扩展 Kubernetes 最常用的方式,在 Service Mesh 和 Operator 中也被大量使用.因此读 ...
- 「工具推荐」golang 代码可视化工具 go-callvis
「工具推荐」go-callvis go-callvis是相对 以图片的形式展示了go程序的调用关系,这个工具在看复杂项目时尤其有用. 亲测,借助它看祖传golang代码,头痛好多了. 安装 go ge ...
- 云原生之旅 - 12)使用 Kaniko 在 Kubernetes上构建 Docker 容器镜像
前言 前一篇文章[云原生之旅 - 11)基于 Kubernetes 动态伸缩 Jenkins Build Agents]有讲到在 Kubernetes Pod (Jenkins build agent ...
- 基于k8s的CI/CD的实现
综述 首先,本篇文章所介绍的内容,已经有完整的实现,可以参考这里. 在微服务.DevOps和云平台流行的当下,使用一个高效的持续集成工具也是一个非常重要的事情.虽然市面上目前已经存在了比较成熟的自动化 ...
- [排序算法] 2路插入排序 (C++)
前言 本文章是建立在 插入排序 的基础上写的,如果还有不懂 插入排序 的童鞋先停下脚步,可以先看看这里~ 直接/折半插入排序 2路插入排序解释 在 插入排序 中,当待插入元素需要插入的位置位于当前有序 ...
- winform的TabContorl的TabPage动态添加滚动条
关键属性 AutoScrollMinSize private int minWidth = 800; private int minHeight = 600; List<Form> li ...
- 关于 .NET 在不同操作系统中 IO 文件路径拼接方法结升级 .NET 7 后注意到的一个小坑
.NET 现在支持跨平台这件事情已经是众所周知的特点了,虽然平台整体支持跨平台了,但是我们的代码如果真的想要实现跨平台运行其实还是有些小细节要注意的,今天想要记录分享的就是关于 文件I/O操作时路径的 ...
- 关于Wegame页面空白的问题解决
前言 前几天帮亲戚家装电脑系统,装好后发现 wegame 所有页面都不能正确加载(全部是空白页面),很神奇,在网上找了很多种解决办法都没有效果,后来不过细心的我发现360浏览器一直提示我证书不安全过期 ...
- K8s安装乐维5.0应用部署文档
乐维产品包具体打包为4个镜像包,分别为:mysql5.7.36.tar.zabbix_server.tar.itops_v1_4_x86_64.tar.bpm0.1.tar,对应的配置文件分别为:da ...