多线程通信

生产者,消费者模式

    • synchronized
    • lock condition对象等待唤醒
    • 线程定制化调用通信

一个线程生产,一个线程消费。

两种实现方式:

  1. synchronized关键字
  2. 灵活的lock锁
一个线程新增1,一个消费0,按顺序进行。保证最后的数据为0;

synchronized

/*等待 唤醒 (生产 通知)* 1. 高内聚的情况下 多线程操作同一个资源* 2. 判断 干活 通知* 3. 防止虚假唤醒 (while 替代if解决)** @author echo lovely* @date 2021/2/17 11:12*//*** thread demo by synchronized keywords*/
class AirCondition {// wait || awaitprivate int num = 0;synchronized void increment() throws InterruptedException {while (num != 0) {// 等待 不生产this.wait();}num++;System.out.println(Thread.currentThread().getName() + "\t" + num);// 唤醒其它线程消费this.notifyAll();}synchronized void decrease() throws InterruptedException {while (num == 0) {// 没有东西 需要等待 不能消费this.wait();}this.num--;System.out.println(Thread.currentThread().getName() + "\t" + num);// 唤醒生产者生产this.notifyAll();}}

private static void waitNotify() {AirCondition ac = new AirCondition();new Thread(() -> {for (int i = 0; i < 10; i++) {try {ac.increment();} catch (InterruptedException e) {e.printStackTrace();}}}, "A").start();new Thread(() -> {for (int i = 0; i < 10; i++) {try {ac.decrease();} catch (InterruptedException e) {e.printStackTrace();}}}, "B").start();new Thread(() -> {for (int i = 0; i < 10; i++) {try {ac.increment();} catch (InterruptedException e) {e.printStackTrace();}}}, "C").start();new Thread(() -> {for (int i = 0; i < 10; i++) {try {ac.decrease();} catch (InterruptedException e) {e.printStackTrace();}}}, "D").start();
}

lock condition对象等待唤醒

/*** thread demo by lock*/
class AirCondition1 {// lock -> product or consumerprivate int num = 0;// 非公平锁private final Lock lock = new ReentrantLock();// 用于lock的等待和唤醒 monitorprivate final Condition condition = lock.newCondition();void increment() {lock.lock();try {while (num != 0) {condition.await();}num++;System.out.println(Thread.currentThread().getName() + "\t" + num);condition.signalAll();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}void decrease() {lock.lock();try {while (num == 0) {// 没有可消费 等待condition.await();}num--;System.out.println(Thread.currentThread().getName() + "\t" + num);// 唤醒生产者生产condition.signalAll();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}}

 private static void awaitSignal() {AirCondition1 condition = new AirCondition1();// thread one productnew Thread(() -> {for (int i = 0; i < 10; i++) {condition.increment();}}, "Rye").start();// thread two consumernew Thread(() -> {for (int i = 0; i < 10; i++) {condition.decrease();}}, "sevenYoungAiRye").start();// thread three productnew Thread(() -> {for (int i = 0; i < 10; i++) {condition.increment();}}, "hh1").start();// thread four consumernew Thread(() -> {for (int i = 0; i < 10; i++) {condition.decrease();}}, "hh2").start();}

线程定制化调用通信

A 线程do sth…
B 线程do sth…
C线程do sthh…

如何保证上面轮询干事?

使用Condtion对象, 拿到对象的锁。

package top.bitqian.demo1;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;/*** 题目:*      三个线程之间 打印 5 10 15 次。轮询打印10次。* @author echo lovely* @date 2021/2/17 18:43*/class ShareData {private int num = 1; // 1 A, 2 B, 3 Cprivate final Lock lock = new ReentrantLock();// 三把钥匙 用于解锁Condition c1 = lock.newCondition();Condition c2 = lock.newCondition();Condition c3 = lock.newCondition();void print5() {try {lock.lock();// 1. 判断while (num != 1) {// 等待c1.await();}// 2. 干活for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + "\t" + i);}// 3. 通知num = 2;// 唤醒第二个线程c2.signal();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}void print10() {try {lock.lock();// 线程2 等待while (num != 2) {c2.await();}for (int i = 0; i < 10; i++) {System.out.println(Thread.currentThread().getName() + "\t" + i);}// 通知三个线程num = 3;c3.signal();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}void print15() {try {lock.lock();while (num != 3) {c3.await();}for (int i = 0; i < 15; i++) {System.out.println(Thread.currentThread().getName() + "\t" + i);}// 通知线程1num = 1;c1.signal();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}}public class ConditionDemo {public static void main(String[] args) {ShareData shareData = new ShareData();new Thread(() -> {for (int i = 0; i < 10; i++) {shareData.print5();}}, "A").start();new Thread(() -> {for (int i = 0; i < 10; i++) {shareData.print10();}}, "B").start();new Thread(() -> {for (int i = 0; i < 10; i++) {shareData.print15();}}, "C").start();}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/420350.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker web程序本地化_Docker-01-Docker介绍

一 什么是虚拟化在计算机中&#xff0c;虚拟化&#xff08;Virtualization&#xff09;是一种资源管理技术&#xff0c;是计算机的各种实体资源&#xff0c;如服务器&#xff0c;网络&#xff0c;内存及存储等&#xff0c;予以抽象&#xff0c;转换后呈现出来&#xff0c;打破实…

tk-mapper 生成器

tk-mapper生成代码代码&#xff0c;项目地址如何使用1. 生成实体类, XML文件, Mapper接口。 2. 版本相关&#xff1a;mapper&#xff1a; 3.4.1mapper-spring-boot-starter: 1.1.2mybatis-generator-core: 1.3.6 3. 这里以SpringBoot为demo, 作为一个程序&#xff0c;运行Gener…

大二《数据结构》机考解题报告

这次学校数据结构机考&#xff0c;题目很奇怪&#xff0c;简直让我觉得这是算法考试……三道题&#xff0c;撑死了用到树的遍历和并查集&#xff0c;连个队列都没用&#xff0c;也是醉了-.- 第一题 高精度加法 两个数相加&#xff0c;数最多5000位&#xff0c;也就是和最多5001…

前端学习(1321):node.js得异步api

const fs require(fs);fs.readFile(./1.txt, utf8, (err, result1) > {console.log(result1);fs.readFile(./2.txt, utf8, (err, result2) > {console.log(result2);fs.readFile(./3.txt, utf8, (err, result3) > {console.log(result3);});}); }) 运行结果

ipad怎么和mac分屏_将Mac屏幕扩展到iPad有多好用?我甚至有了入手iPad Pro的冲动...

这次我手机先不升 iOS 13&#xff0c;不够稳&#xff0c;但 iPadOS 更新这么多&#xff0c;我是绝对会升的。手捧 11 英寸 iPad Pro 几个月&#xff0c;但却一直只把它当做大号 iPod Touch 的朋友在看完《iPadOS 抢先体验&#xff1a;这是一次属于 iPad 的成人礼》这篇文章后对…

SpringBoot配置文件绑定到Java Bean

boot读取配置文件1. yml配置文件2. 绑定方式13. 绑定方式23.1 依赖.3.2 boot 中提供的属性装配功能。1. 在某些业务中&#xff0c;需要将类的配置写到配置文件中, 不在代码中写死配置。 2. 所以需要读取配置文件(yaml, properties) 读取到Java Bean中。 3. 本文以oss对象存储配…

Ruby学习-第二章

第二章 类继承&#xff0c;属性&#xff0c;类变量 1.如何声明一个子类 class Treasure < Thing 这样Thing类中的属性name&#xff0c;description都被Treasure继承 2.以下三种方式传入父类initialize方法的参数分别是什么&#xff1f; # This passes a, b, c to the superc…

面向接口编程的优点_为什么我们要面向接口编程

到底面向&#xff1f;编程面向过程编程( ProcedureOriented、简称 PO) 和 面向对象编程( ObjectOriented、简称 OO) 我们一定听过&#xff0c;然而实际企业级开发里受用更多的一种编程思想那就是&#xff1a;面向接口编程( Interface-Oriented)&#xff01;接口这个概念我们一定…

设计模式:设计原则

程序设计的原则1. 单一设计原则2. 接口隔离原则3. 依赖倒转4. 里氏替换原则5. 开闭原则6. 迪米特原则7. 合成复用1. 单一设计原则 每一个类只负责做自己的的功能。不能跨越到其它类。 不合理 package top.bitqian.principle.single_responsibility;/*** author echo lovely* …

Android数据库LitePal的存储操作

本文属于转载&#xff0c;在此声明&#xff0c;出处&#xff1a;http://blog.csdn.net/guolin_blog/article/details/38556989 并且感谢guolin分享了这么精彩的博文。以下正文&#xff1a; 经过前面几篇文章的学习&#xff0c;我们已经把LitePal的表管理模块的功能都很好地掌握…

程控电源测试微安电流模式_无缝隙源和负载的切换:双向程控电源的一大门槛...

目前采用电池供电的直流无刷电机驱动的设备越来越多&#xff0c;从电动工具&#xff0c;无人机、机器人、再到电动汽车等。然而电机驱动器和电池的管理始终是研发工程师不得不面对的一道难题。电动机利用的是“电生磁”原理&#xff0c;把电能转换成机械能。但制动&#xff0c;…

前端学习(1324):anysc关键字

//只能出现再异步函数中 暂停异步函数得执行 async function fn() {throw 发生勒一些错误;return 123; } //console.log(fn()) fn().then(function(data) {console.log(data); }).catch(function(err) {console.log(err); }) 运行结果

Pacman主题下给Hexo增加简历类型

原文 http://blog.zanlabs.com/2015/01/02/add-resume-type-to-hexo-under-pacman-theme/ 背景 虽然暂时不找工作&#xff0c;但是想着简历也是个向别人推销自己的好东西。然后也想着折腾点新的东西&#xff0c;如此&#xff0c;这般&#xff0c;便想着研究起写个简历了。形式不…

屏幕输出语句_C语言快速入门——表达式与语句

表达式表达式是由运算符和操作数组合构造成。最简单的表达式是一个单独的操作数&#xff0c;以此作为基础&#xff0c;结合语言自身支持的操作符&#xff0c;就可以建立复杂的表达式。下面是一些表达式&#xff1a;从这里可以看到&#xff0c;操作数可以是数据常量(4&#xff0…

前端学习(1325):await关键字

async function p1() {return p1; } async function p2() {return p2; } async function p3() {return p3; } async function run() {let r1 await p1();let r2 await p2();let r3 await p3();console.log(r1);console.log(r2);console.log(r3);} run(); 运行结果

接口测试客户端的搭建

一. 引言 随着公司项目整体架构由原来的多渠道各自为战&#xff0c;向着建立统一的服务端应用&#xff0c;从而为各渠道提供服务调用的转变&#xff0c;服务端应用接口测试成了我们日常工作中的重要任务之一。经过半年的摸索和项目实战&#xff0c;我们已经掌握了一套接口测试的…

python对excel数据求和_96、python操作excel求和

这里介绍如何用python来自动完成我们的excel工作。本文的目的是展示一些常见的Excel任务&#xff0c;以及如何在python pandas中执行类似的任务。例子微不足道&#xff0c;但重要的是通过这个例子来循序渐进的介绍pandas简单到复杂的功能。展示pandas如何利用Python的完整的模块…

前端学习(1327):node全局对象global

global.console.log(我是歌谣); global.setTimeout(function() {console.log(123); }, 2000) 运行结果

4字节 经纬度_java 获取本机经纬度

package com.smm.web.mtower.util;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.net.URL;/*** Created by zhenghao on 2016/6/24.* 当前位置处理工具*/public class LocationUtil {/*…