线程通信之定制化

之前文章中写了下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之线程间定制化通信的更多相关文章

  1. JUC之线程间的通信

    线程通信 视频1: 2021.12.18 JUC视频学习片段 对上次多线程编程步骤补充(中部): 创建资源类,在资源类中创建属性和操作方法 在资源类里面操作 判断 干活 通知 创建多个线程,调用资源类 ...

  2. 线程间使用socket通信的计算器

    该程序是处理平时的算数运算,程序也没有什么特别之处,只是将所有运算分开运算,每个函数(线程)处理不同的运算符号里面的运算,然后将所有结果都汇总到main函数中进行最后汇总(相加减)运算,每个函数内都处 ...

  3. iOS开发之线程间的MachPort通信与子线程中的Notification转发

    如题,今天的博客我们就来记录一下iOS开发中使用MachPort来实现线程间的通信,然后使用该知识点来转发子线程中所发出的Notification.简单的说,MachPort的工作方式其实是将NSMa ...

  4. linux c 线程间同步(通信)的几种方法--互斥锁,条件变量,信号量,读写锁

    Linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量.信号量和读写锁. 下面是思维导图:  一.互斥锁(mutex)  锁机制是同一时刻只允许一个线程执行一个关键部分的代码. 1 . ...

  5. rtt学习之线程间同步与通信

    一 线程间的同步与互斥:信号量.互斥量.实践集 线程互斥是指对于临界区资源访问的排它性,如多个线程对共享内存资源的访问,生产消费型对产品的操作.临界区操作操作方法有: rt_hw_interrupt_ ...

  6. 线程间通过PostMessage通信

    1.查看TMS项目中的相关实例 ::PostMessage(hWnd, WM_USER_MSG_REFRESH_UI, (WPARAM)UMP_REFRESH_MEMBER_INFO, 0); 参考文 ...

  7. JUC---06线程间通信(二)

    二.线程间定制化调用通信 要使多线程之间按顺序调用,实现A->B->C按顺序输出,使用Lock锁实现,通过Lock锁创建三个Condition实例(三把钥匙),通过不同的条件,调用不同钥匙 ...

  8. Java多线程编程核心技术---线程间通信(二)

    通过管道进行线程间通信:字节流 Java提供了各种各样的输入/输出流Stream可以很方便地对数据进行操作,其中管道流(pipeStream)是一种特殊的流,用于在不同线程间直接传送数据,一个线程发送 ...

  9. C++多线程编程(三)线程间通信

    多线程编程之三——线程间通讯 作者:韩耀旭 原文地址:http://www.vckbase.com/document/viewdoc/?id=1707 七.线程间通讯 一般而言,应用程序中的一个次要线 ...

随机推荐

  1. 2021广东工业大学新生赛决赛 L-歪脖子树下的灯

    题目:L-歪脖子树下的灯_2021年广东工业大学第11届腾讯杯新生程序设计竞赛(同步赛) (nowcoder.com) 比赛的时候没往dp这方面想(因为之前初赛和月赛数学题太多了啊),因此只往组合数学 ...

  2. Rest使用get还是post

    1. get是从服务器上获取数据,post是向服务器传送数据. 2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到.post是通过 ...

  3. Git上项目代码拉到本地方法

    1.先在本地打开workspace文件夹,或者自定义的文件夹,用来保存项目代码的地方. 2.然后登陆GitHub账号,点击复制项目路径 3.在刚才文件夹下空白处点击鼠标右键,打开Git窗口 4.在以下 ...

  4. error信息

    /opt/hadoop/src/contrib/eclipse-plugin/build.xml:61: warning: 'includeantruntime' was not set, defau ...

  5. 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",这个配置严 ...

  6. 【Linux】【Service】【OpenSSL】原理及实现

    1. 概念 1.1. SSL(Secure Sockets Layer安全层套接字)/TLS(Transport Layer Security传输层套接字). 最常见的应用是在网站安全方面,用于htt ...

  7. 【Java 8】 Reduce方法

    一:reduce rudece方法:从一个流中生成一个值 三个重载方法: Optional<T> reduce(BinaryOperator<T> accumulator); ...

  8. Win10 Chrome 在DPI缩放下导致界面放大问题 解决方案

    支持:54.0.2840.59 m (64-bit) 以下大多数版本,具体未测试.如有问题可以反馈一下. 方法1:为程序设置"高DPI设置时禁用显示缩放. 方法2:为程序添加启动参数: /h ...

  9. 将前端请求中的数据绑定到Spring MVC响应方法中参数的四种方法

    一.映射URL绑定的占位符到方法参数 1.方法 使用@PathVariable注解 2.代码示例 a.接收请求方法 @RequestMapping(value = "/deleteInfo/ ...

  10. Docker从入门到精通(一)——初识

    1.Docker 是什么? Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容 ...