线程通信之定制化

之前文章中写了下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. 商业爬虫学习笔记day8-------json的使用

    一. 简介 JSON,全称为JavaScript Object Notation(JavaScript对象标记),它通过对象和数组的组合来表示数据,是一种轻量级的数据交换格式.它基于 ECMAScri ...

  2. Output of C++ Program | Set 5

    Difficulty Level: Rookie Predict the output of below C++ programs. Question 1 1 #include<iostream ...

  3. jQuery中的html()、text()和val()的用法

    1.html() 获得的是第一个符合要求的标签中的所有内容,例如: var content = $("li").html(); <li>111<p>999& ...

  4. 前端避坑指南丨辛辛苦苦开发的 APP 竟然被判定为简单网页打包?

    传统混合移动App开发模式,通常会使用WebView作为桥接层,但随着iOS和Android应用商店审核政策日趋严格,有时会被错误判定为简单网页打包成App,上架容易遭到拒绝. 既然可能存在风险,那我 ...

  5. vue-cli4结合element-ui异常解决(前端小白,文摘取自网络)

    1:将vue-cli4版本退回到vue-cli3 2:使用element-plus 替换 element-ui 传送门 => https://element-plus.gitee.io/#/zh ...

  6. react功能实现-组件创建

    这里主要从两个角度来分析创建一个组件需要怎么做,一个是元素,一个是数据.整理向,大量借鉴,非原创. 1.渲染组件. 我们先明确一点,所有的元素都必须通过render方法来输出渲染.所有,每个组件类最终 ...

  7. 【Python机器学习实战】聚类算法(2)——层次聚类(HAC)和DBSCAN

    层次聚类和DBSCAN 前面说到K-means聚类算法,K-Means聚类是一种分散性聚类算法,本节主要是基于数据结构的聚类算法--层次聚类和基于密度的聚类算法--DBSCAN两种算法. 1.层次聚类 ...

  8. CF94A Restoring Password 题解

    Content 有一个 \(80\) 位的 \(01\) 字符串,由 \(8\) 个长度为 \(10\) 的 \(01\) 字符串组成,每个小字符串分别对应一个数字.现在,给出这个字符串和 \(0\) ...

  9. MySQL、Oracle元数据抽取分析

    最近接到个任务是抽取mysql和Oracle的元数据,大致就是在库里把库.schema.表.字段.分区.索引.主键等信息抽取出来,然后导成excel. 因为刚开始接触元数据,对这个并不了解,就想借助一 ...

  10. .NET 6 优先队列 PriorityQueue 实现分析

    在最近发布的 .NET 6 中,包含了一个新的数据结构,优先队列 PriorityQueue, 实际上这个数据结构在隔壁 Java中已经存在了很多年了, 那优先队列是怎么实现的呢? 让我们来一探究竟吧 ...