当前位置: 首页 > news >正文

线程间通信


线程间通信的模型有两种:共享内存 和 消息传递,以下方式都是基本这两种模型来实现的。

场景—两个线程,一个线程对当前数值加 1,另一个线程对当前数值减 1。要求用线程间通信

3.1 synchronized方案


使用 wait(); notify();

public class TestMain { /** ● 交替加减*/ public static void main(String[] args){ DemoClass demoClass = new DemoClass();         new Thread(() ->{             for (int i = 0; i < 5; i++) { demoClass.increment(); } }, "线程 A").start(); new Thread(() ->{             for (int i = 0; i < 5; i++) {                 demoClass.decrement(); } }, "线程 B").start(); } 
} 
class DemoClass{     //加减对象 private int number = 0; /** * 加 1 */ public synchronized void increment() { try { while (number != 0){ this.wait(); } number++; System.out.println(currentThread().getName() + "加一成功,值为:" + number); //唤醒其他的线程notifyAll(); }catch (Exception e){ e.printStackTrace(); } } /** * 减一 */ public synchronized void decrement(){ try { while (number != 1){ this.wait(); } number--; System.out.println(currentThread().getName() + "减一成功,值为:" + number); notifyAll(); }catch (Exception e){ e.printStackTrace(); } } 
} 

3.2 Lock 方案


使用 Condition condition.await(); condition.signal();

import java.util.concurrent.locks.Condition; 
import java.util.concurrent.locks.Lock; 
import java.util.concurrent.locks.ReentrantLock; class DemoClass{     // 加减对象 private int number = 0; // 声明锁     private Lock lock = new ReentrantLock(); // 声明钥匙 private Condition condition = lock.newCondition(); /** * 加 1 */ public void increment() { try {             lock.lock(); // 加锁        while (number != 0){                 condition.await();  //等待} number++; System.out.println(currentThread().getName() + "加一成功,值为:" + number);//	通知其他等待的线程condition.signalAll(); }catch (Exception e){ e.printStackTrace();         }finally {             lock.unlock(); //释放锁} } /** * 减一 */ public void decrement(){ try {             lock.lock();             while (number != 1){                 condition.await(); } number--; System.out.println(currentThread().getName() + "减一成功,值为:" + number); condition.signalAll(); }catch (Exception e){ e.printStackTrace();         }finally {             lock.unlock();                                                   } } 
} 
import java.util.concurrent.locks.Condition; 
import java.util.concurrent.locks.Lock; 
import java.util.concurrent.locks.ReentrantLock; class DemoClass{ //通信对象:0--打印 A  1---打印 B  2----打印 C private int number = 0; //声明锁     private Lock lock = new ReentrantLock(); //声明钥匙 A private Condition conditionA = lock.newCondition(); //声明钥匙 B private Condition conditionB = lock.newCondition(); //声明钥匙 C private Condition conditionC = lock.newCondition(); 
}

3.4 线程间定制化通信


3.4.1 案例介绍

问题: A 线程打印 5 次 A,B 线程打印 10 次 B,C 线程打印 15 次 C 。

按照此顺序循环 10 轮

3.4.2 实现流程

代码如下:

//	标志位 AA 1   BB 2  CC 3
private int number = 1; Lock lock = new ReentrantLock();
private Condition conditionA = lock.newCondition(); 
private Condition conditionB = lock.newCondition(); 
private Condition conditionC = lock.newCondition(); //	5 次
public void printA(int j){ try {             lock.lock();             while (number != 1){conditionA.await(); } System.out.println(currentThread().getName() + "输出 A,第" + j + " 轮开始"); // 输出 5 次 A for (int i = 0; i < 5; i++) { System.out.println("A"); } // 修改标志位           number = 2;             //唤醒 BconditionB.signal(); } catch (Exception e){ e.printStackTrace();         } finally {lock.unlock(); } 
} //	10 次
public void printB(int j){ try {             lock.lock();while (number != 2){conditionB.await(); } System.out.println(currentThread().getName() + "输出 B,第" + j + " 轮开始"); //输出 10 次 B for (int i = 0; i < 10; i++) { System.out.println("B"); } // 修改标志位number = 3;//唤醒 CconditionC.signal(); } catch (Exception e){ e.printStackTrace();         }finally {lock.unlock(); }
}//	15 次
public void printC(int j){ try {             lock.lock();while (number != 3){conditionC.await(); } System.out.println(currentThread().getName() + "输出 C,第" + j + " 轮开始"); //输出 15 次 C for (int i = 0; i < 15; i++) { System.out.println("C"); } System.out.println("-----------------------------------------"); //	修改标志位number = 1;//唤醒 AconditionA.signal(); } catch (Exception e){ e.printStackTrace(); } finally {lock.unlock(); } 
} 

测试类

/** 
● 关键字实现线程交替加减 
*/ 
public class TestVolatile { /** ● 交替加减 ● @param args */ public static void main(String[] args){ DemoClass demoClass = new DemoClass(); new Thread(() ->{             for (int i = 1; i <= 10; i++) {                 demoClass.printA(i); } }, "A 线程").start(); new Thread(() ->{for (int i = 1; i <= 10; i++) { demoClass.printB(i); } }, "B 线程").start(); new Thread(() ->{for (int i = 1; i <= 10; i++) {demoClass.printC(i); } }, "C 线程").start(); } 
} 


文章转载自:

http://EWadU50e.wmhLz.cn
http://9GgN2Qjy.wmhLz.cn
http://LziCgCfJ.wmhLz.cn
http://HsdlW8Ny.wmhLz.cn
http://K6tH48y7.wmhLz.cn
http://MT9XWKtN.wmhLz.cn
http://RaaWnZhI.wmhLz.cn
http://HxZ1u9YA.wmhLz.cn
http://XN4ngIgx.wmhLz.cn
http://9axReIXR.wmhLz.cn
http://oRmYGGS9.wmhLz.cn
http://54KSGjNO.wmhLz.cn
http://beL2IMe3.wmhLz.cn
http://jrMAMH3F.wmhLz.cn
http://tqcBX7Ut.wmhLz.cn
http://0GhRM2MU.wmhLz.cn
http://xHJWAuHl.wmhLz.cn
http://LLmYntq0.wmhLz.cn
http://3LfbLyWG.wmhLz.cn
http://jEjcZ9TD.wmhLz.cn
http://XNBvFEiW.wmhLz.cn
http://uarF9n83.wmhLz.cn
http://dGWEPl5f.wmhLz.cn
http://urI2IWyu.wmhLz.cn
http://sQPske6J.wmhLz.cn
http://NeIOU4AH.wmhLz.cn
http://vSLTWf5P.wmhLz.cn
http://xmajhMAy.wmhLz.cn
http://vtAq4B4r.wmhLz.cn
http://0qUF10Si.wmhLz.cn
http://www.dtcms.com/a/371484.html

相关文章:

  • 文件上传之读取文件内容保存到ES
  • 图神经网络分享系列-SDNE(Structural Deep Network Embedding) (一)
  • sentinel限流常见的几种算法以及优缺点
  • 【贪心算法】day6
  • CSS(展示效果)
  • 基于原神游戏物品系统小demo制作思路
  • docker,本地目录挂载
  • The Xilinx 7 series FPGAs 设计PCB 该选择绑定哪个bank引脚,约束引脚时如何定义引脚电平标准?
  • 算法:选择排序+堆排序
  • UE4/UE5反射系统动态注册机制解析
  • 【开题答辩全过程】以 汽车知名品牌信息管理系统为例,包含答辩的问题和答案
  • rabbitmq 的 TTL
  • Linux内核网络的连接跟踪conntrack简单分析
  • Java Stream流:从入门到精通
  • java常见面试题杂记
  • SAP匈牙利新闻
  • Java全栈工程师的面试实战:从基础到高阶技术解析
  • 计算机毕设选题:基于Python+Django的B站数据分析系统的设计与实现【源码+文档+调试】
  • 【嵌入式】【树莓派】【大疆PSDK】用树莓派4B开发大疆行业无人机应用系统小结-【硬件篇】
  • 深度学习——自然语言处理NLP
  • 灾难性遗忘:神经网络持续学习的核心挑战与解决方案
  • bug | 事务粒度不能太大,含demo
  • 如何建立针对 .NET Core web 程序的线程池的长期监控
  • 41个开源大语言模型基准测试报告
  • unsloth 笔记:从最近的检查点继续微调
  • 区域导航系统 | 印度区域卫星导航系统(IRNSS/NavIC)深度解析
  • Linux服务器资源自动监控与报警脚本详解
  • 社交新零售时代本地化微商的发展路径研究——基于开源AI智能名片链动2+1模式S2B2C商城小程序源的创新实践
  • Tailwind CSS v4 终极指南:体验 Rust 驱动的闪电般性能与现代化 CSS 工作流
  • 模块--红外跟随避障模块