JUC之线程间定制化通信
线程通信之定制化
之前文章中写了下Condition的使用,这里我们详细说下其中的用法:
首先使用Condition需要实例化Lock
private Lock lock = new ReentrantLock(); //创建锁
使用lock里面的newCondition方法创建Condition对象:
private Condition c1 = lock.newCondition();
其优点:比synchronized更安全、更高效。
选自:廖雪峰的官网-Java教程
Condition
提供的await()
、signal()
、signalAll()
原理和synchronized
锁对象的wait()
、notify()
、notifyAll()
是一致的,并且其行为也是一样的:
await()
会释放当前锁,进入等待状态;signal()
会唤醒某个等待线程;signalAll()
会唤醒所有等待线程;- 唤醒线程从
await()
返回后需要重新获得锁。
需要注意的是上面signal\signalAll与await方法的对应关系;
通过一个例子来理解线程间的定制化:
要求:
实现代码:
package com.JUC;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//线程间的定制化通信
class ShareRewsource {
private int flag = 1; //1表示线程AAA,2表示线程BBB,3表示线程CCC
private Lock lock = new ReentrantLock(); //创建锁
//代替Object中的等待、唤醒等操作,更加的安全高效
private Condition c1 = lock.newCondition(); //对标AAA线程
private Condition c2 = lock.newCondition(); //对标BBB线程
private Condition c3 = lock.newCondition(); //对标CC线程
//创建方法
public void print5(int loop) {
lock.lock();
try {
while (flag != 1) {
c1.await();
}
//操作
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + "-----" + i + "::" + loop);
}
flag = 2;
c2.signal(); //通知BBB线程 唤醒BBB线程,唤醒后在BBB线程的await后继续执行;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
//创建方法
public void print10(int loop) {
lock.lock();
try {
while (flag != 2) {
c2.await();
}
//操作
for (int i = 1; i <= 10; i++) {
System.out.println(Thread.currentThread().getName() + "-----" + i + "::" + loop);
}
flag = 3;
c3.signal(); //通知CCC线程
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
//创建方法
public void print15(int loop) {
lock.lock();
try {
while (flag != 3) {
c3.await();
}
//操作
for (int i = 1; i <= 15; i++) {
System.out.println(Thread.currentThread().getName() + "-----" + i + "::" + loop);
}
flag = 1;
c1.signal(); //通知AAA线程
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public class ThreadPrivateDemo {
public static void main(String[] args) {
ShareRewsource rewsource = new ShareRewsource();
new Thread(() -> {
for (int i = 1; i <= 10; i++) {
rewsource.print5(i);
}
}, "AAA").start();
new Thread(() -> {
for (int i = 1; i <= 10; i++) {
rewsource.print10(i);
}
}, "BBB").start();
new Thread(() -> {
for (int i = 1; i <= 10; i++) {
rewsource.print15(i);
}
}, "CCC").start();
}
}
其中对应关系:注意唤醒和等待所在的代码段
c2.signal() --> c2.await()
c3.signal() --> c3.await()
c1.signal() --> c1.await()
JUC之线程间定制化通信的更多相关文章
- JUC之线程间的通信
线程通信 视频1: 2021.12.18 JUC视频学习片段 对上次多线程编程步骤补充(中部): 创建资源类,在资源类中创建属性和操作方法 在资源类里面操作 判断 干活 通知 创建多个线程,调用资源类 ...
- 线程间使用socket通信的计算器
该程序是处理平时的算数运算,程序也没有什么特别之处,只是将所有运算分开运算,每个函数(线程)处理不同的运算符号里面的运算,然后将所有结果都汇总到main函数中进行最后汇总(相加减)运算,每个函数内都处 ...
- iOS开发之线程间的MachPort通信与子线程中的Notification转发
如题,今天的博客我们就来记录一下iOS开发中使用MachPort来实现线程间的通信,然后使用该知识点来转发子线程中所发出的Notification.简单的说,MachPort的工作方式其实是将NSMa ...
- linux c 线程间同步(通信)的几种方法--互斥锁,条件变量,信号量,读写锁
Linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量.信号量和读写锁. 下面是思维导图: 一.互斥锁(mutex) 锁机制是同一时刻只允许一个线程执行一个关键部分的代码. 1 . ...
- rtt学习之线程间同步与通信
一 线程间的同步与互斥:信号量.互斥量.实践集 线程互斥是指对于临界区资源访问的排它性,如多个线程对共享内存资源的访问,生产消费型对产品的操作.临界区操作操作方法有: rt_hw_interrupt_ ...
- 线程间通过PostMessage通信
1.查看TMS项目中的相关实例 ::PostMessage(hWnd, WM_USER_MSG_REFRESH_UI, (WPARAM)UMP_REFRESH_MEMBER_INFO, 0); 参考文 ...
- JUC---06线程间通信(二)
二.线程间定制化调用通信 要使多线程之间按顺序调用,实现A->B->C按顺序输出,使用Lock锁实现,通过Lock锁创建三个Condition实例(三把钥匙),通过不同的条件,调用不同钥匙 ...
- Java多线程编程核心技术---线程间通信(二)
通过管道进行线程间通信:字节流 Java提供了各种各样的输入/输出流Stream可以很方便地对数据进行操作,其中管道流(pipeStream)是一种特殊的流,用于在不同线程间直接传送数据,一个线程发送 ...
- C++多线程编程(三)线程间通信
多线程编程之三——线程间通讯 作者:韩耀旭 原文地址:http://www.vckbase.com/document/viewdoc/?id=1707 七.线程间通讯 一般而言,应用程序中的一个次要线 ...
随机推荐
- 2021广东工业大学新生赛决赛 L-歪脖子树下的灯
题目:L-歪脖子树下的灯_2021年广东工业大学第11届腾讯杯新生程序设计竞赛(同步赛) (nowcoder.com) 比赛的时候没往dp这方面想(因为之前初赛和月赛数学题太多了啊),因此只往组合数学 ...
- Rest使用get还是post
1. get是从服务器上获取数据,post是向服务器传送数据. 2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到.post是通过 ...
- Git上项目代码拉到本地方法
1.先在本地打开workspace文件夹,或者自定义的文件夹,用来保存项目代码的地方. 2.然后登陆GitHub账号,点击复制项目路径 3.在刚才文件夹下空白处点击鼠标右键,打开Git窗口 4.在以下 ...
- error信息
/opt/hadoop/src/contrib/eclipse-plugin/build.xml:61: warning: 'includeantruntime' was not set, defau ...
- mysql 执行报错:Error querying database. Cause: java.sql.SQLSyntaxErrorException:which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
1.这个错误发生在mysql 5.7 版本及以上版本会出现的问题: mysql 5.7版本默认的sql配置是:sql_mode="ONLY_FULL_GROUP_BY",这个配置严 ...
- 【Linux】【Service】【OpenSSL】原理及实现
1. 概念 1.1. SSL(Secure Sockets Layer安全层套接字)/TLS(Transport Layer Security传输层套接字). 最常见的应用是在网站安全方面,用于htt ...
- 【Java 8】 Reduce方法
一:reduce rudece方法:从一个流中生成一个值 三个重载方法: Optional<T> reduce(BinaryOperator<T> accumulator); ...
- Win10 Chrome 在DPI缩放下导致界面放大问题 解决方案
支持:54.0.2840.59 m (64-bit) 以下大多数版本,具体未测试.如有问题可以反馈一下. 方法1:为程序设置"高DPI设置时禁用显示缩放. 方法2:为程序添加启动参数: /h ...
- 将前端请求中的数据绑定到Spring MVC响应方法中参数的四种方法
一.映射URL绑定的占位符到方法参数 1.方法 使用@PathVariable注解 2.代码示例 a.接收请求方法 @RequestMapping(value = "/deleteInfo/ ...
- Docker从入门到精通(一)——初识
1.Docker 是什么? Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容 ...