线程通信之定制化

之前文章中写了下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. 在JTable单元格上 加入组件,并赋予可编辑能力 [转]

    表格(单元格放置组件) 对于JTable单元格的渲染主要是通过两个接口来实现的,一个是TableCellRenderer另一个是TableCellEditor,JTable默认是用的是DefaultC ...

  2. k8s配置中心-configmap,Secret密码

    目录 k8s配置中心-configmap,Secret 创建ConfigMap 使用ConfigMap subPath参数 Secret 官方文档 编写secret清单 使用secret 在 Pod ...

  3. Shell学习(九)——chattr与lsattr命令详解

    有时候你发现用root权限都不能修改某个文件,大部分原因是曾经用chattr命令锁定该文件了.chattr命令的作用很大,其中一些功能是由Linux内核版本来支持的,不过现在生产绝大部分跑的linux ...

  4. springboot整合jetty

    1.jetty介绍 通常我们进行Java Web项目开发,必须要选择一种服务器来部署并运行Java应用程序,Tomcat和Jetty作为目前全球范围内最著名的两款开源servlet容器,该怎么选呢. ...

  5. 【Java】【IDE】【Jetbrain Idea】Intellij IDEA 快捷键整理

    [常规] Ctrl+Shift + Enter,语句完成 "!",否定完成,输入表达式时按 "!"键 Ctrl+E,最近的文件 Ctrl+Shift+E,最近更 ...

  6. BigDecimal 中 关于RoundingMode介绍

    RoundingMode介绍 RoundingMode是一个枚举类,有以下几个常量:UP.DOWN.CEILING.FLOOR.HALF_UP.HALF_DOWN.HALF_EVEN.UNNECESS ...

  7. 【力扣】两个数组的交集 II

    给定两个数组,编写一个函数来计算它们的交集. 示例 1: 输入:nums1 = [1,2,2,1], nums2 = [2,2]输出:[2,2]示例 2: 输入:nums1 = [4,9,5], nu ...

  8. C#.NET编程小考30题错题纠错

    1)以下关于序列化和反序列化的描述错误的是( C). a) 序列化是将对象的状态存储到特定存储介质中的过程 b) 二进制格式化器的Serialize()和Deserialize()方法可以分别用来实现 ...

  9. 象群游牧算法-Matlab

    1. 适应度函数: function z=chaffer(x)%chaffer函数x=(0...0) f(x)=0 x[-10,10]%%没测 n=10; s1=0; for i=1:n s1=s1+ ...

  10. Kafka从入门到放弃(三)—— 详说消费者

    之前介绍了Kafka以及生产者,包括它的一些特性和参数,这回写一下消费者. 之前没看得可以点击链接阅读. Kafka从入门到放弃(一) -- 初识Kafka Kafka从入门到放弃(二) -- 详说生 ...