线程基础知识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类的 ...
随机推荐
- js和jquery页面初始化加载函数的方法及顺序
运行下面代码.弹出A.B.C.D.E的顺序:A=B=C>D=E. <html> <head> <title>首页</title> <scri ...
- 记录一次新节点加入K8S集群
新节点初始化 安装docker kubelet kubeadm(指定版本) #先查看当前集群docker版本 [root@lecode-k8s-master manifests]# docker ve ...
- 更换linux的开机启动图片, 启动主题
简述 之前就想更改开机的启动图片,但是后来简单查了一下,说要重新编译内核,听到编译我就望而却步了,今天发现只是个命令而已,注意这里我用的是 linux mint .这里更改不是 grub 主题, 是 ...
- 关于sublime text 3写一个插件
前言 我之前一直想写一个记录自己笔记的软件,可以给因为我都记录在桌面的便签上很乱,以至于便签上满满的全是字母,很难看,但是我有不想写图形化界面,所以最终我选择了写一个sublime 插件,功能就是记录 ...
- SpringCloud Alibaba(二) - Sentinel,整合OpenFeign,GateWay服务网关
1.环境准备 1.1Nacos 单机启动:startup.cmd -m standalone 1.2 Sentinel 启动命令:java -Dserver.port=8858 -Dcsp.senti ...
- JS逆向实战9——cookies DES加密混淆
cookie加密 DES 混淆 目标网站:aHR0cHM6Ly90bGNoZW1zaG9wLnlvdXpoaWNhaS5jb20vbWFpbi90ZW5kP05vdGljZUNhdGVJZD0xJk5 ...
- 基于 RocketMQ 的 Dubbo-go 通信新范式
本文作者:郝洪范 ,Dubbo-go Committer,京东资深研发工程师. 一.MQ Request Reply特性介绍 什么是 RPC 通信? 如上图所示,类似于本地调用,A 服务响应调用 B ...
- 【每日一题】【栈和队列、双端队列】20. 有效的括号/NC52 有效括号序列-211127/220126
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭合.左括号必须以正确的顺序闭合. 来源:力扣(L ...
- 高可用系列文章之三 - NGINX 高可用实施方案
前文链接 高可用系列文章之一 - 概述 - 东风微鸣技术博客 (ewhisper.cn) 高可用系列文章之二 - 传统分层架构技术方案 - 东风微鸣技术博客 (ewhisper.cn) 四 NGINX ...
- [编程基础] Python配置文件读取库ConfigParser总结
Python ConfigParser教程显示了如何使用ConfigParser在Python中使用配置文件. 文章目录 1 介绍 1.1 Python ConfigParser读取文件 1.2 Py ...