线程通信之定制化

之前文章中写了下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. 单体内置对象 Global 和 Math

    单体内置对象 Global 和 Math 在所有代码执行前,作用域中就已经存在两个内置对象:Global(全局)和Math.在大多数ES实现中都不能直接访问Global对象.不过,WEB浏览器实现了承 ...

  2. cordova配置与开发

    1.环境配置 1.1.安装ant 从 apache官网 下载ant,安装并配置,将ant.bat所在目录加到path环境变量,如c:\apache-ant\bin\.在cmd中运行以下语句如不报错即可 ...

  3. Linux_spool命令

    spool的作用是什么? spool的作用可以用一句话来描述:在sqlplus中用来保存或打印查询结果. 参数指南 对于SPOOL数据的SQL,最好要自己定义格式,以方便程序直接导入,SQL语句如: ...

  4. Activiti工作流引擎使用详解(一)

    一.IDEA安装activiti插件 在插件库中查找actiBPM,安装该插件,如果找不到该插件,请到插件库中下载该包手动安装,插件地址 http://plugins.jetbrains.com/pl ...

  5. SpringBoot项目找不到主类或无法加载主类

    问题描述 启动springboot项目的时候发现启动失败,查看日志发现因为找不到主类或无法加载主类. 解决 我这个项目是拉取的别人git上的项目,看了一下目录结构发现没有编译后的文件(target目录 ...

  6. ASP.NET Core中使用漏桶算法限流

    漏桶算法是限流的四大主流算法之一,其应用场景各种资料中介绍的不多,一般都是说应用在网络流量控制中.这里举两个例子: 1.目前家庭上网都会限制一个固定的带宽,比如100M.200M等,一栋楼有很多的用户 ...

  7. python自带性能强悍的标准库 itertools

    可迭代对象就像密闭容器里的水,有货倒不出 itertools是python内置的标准模块,提供了很多简洁又高效的专用功能,使用得当能够极大的简化代码行数,同时所有方法都是实现了生成器函数,这就意味着极 ...

  8. 04 - Vue3 UI Framework - 文档页

    官网的首页做完了,接下来开始做官网的文档页 返回阅读列表点击 这里 路由设计 先想想我们需要文档页通向哪些地方,这里直接给出我的设计: 所属 子标题 跳转路径 文件名(*.vue) 指南 介绍 /do ...

  9. Redis集群环境各节点无法互相发现与Hash槽分配异常 CLUSTERDOWN Hash slot not served的解决方式

    总结/朱季谦 在搭建Redis5.x版本的集群环境曾出现各节点无法互相发现与Hash槽分配异常 CLUSTERDOWN Hash slot not served的情况,故而把解决方式记录下来. 在以下 ...

  10. Apache log4j2 远程代码执行漏洞复现👻

    Apache log4j2 远程代码执行漏洞复现 最近爆出的一个Apache log4j2的远程代码执行漏洞听说危害程度极大哈,我想着也来找一下环境看看试一下.找了一会环境还真找到一个. 漏洞原理: ...