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

多线程顺序打印ABC的两种实现方式:synchronized与Lock机制

目录

方案一:Lock + Condition 机制

方案二:synchronized 机制

两种方案的对比


   在多线程编程中,线程间的通信和同步是核心问题之一。本文将通过一个经典案例:三个线程分别打印3次A、5次B、6次C,并且按照A→B→C→A的顺序循环执行,来详细介绍Java中两种线程同步机制的实现方式。

方案一:Lock + Condition 机制

        使用ReentrantLock配合多个Condition实现精确的线程间通信,每个Condition对应一个线程的等待队列,可以实现精确唤醒。

package com.demo1;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class PrintChar {// 计数器变量private int num = 0;Lock lock = new ReentrantLock();// 创建监视器Condition c1 = lock.newCondition();Condition c2 = lock.newCondition();Condition c3 = lock.newCondition();// 3次Apublic void showA() {while (true) {lock.lock();if (num != 0) {try {this.c1.await();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}for (int i = 0; i < 3; i++) {System.out.println(Thread.currentThread().getName() + ",A");}try {Thread.sleep(2000);num = 1;this.c2.signal();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}lock.unlock();}}// 5次Bpublic void showB() {while (true) {lock.lock();if (num != 1) {try {this.c2.await();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + ",B");}try {Thread.sleep(2000);num = 2;this.c3.signal();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}lock.unlock();}}// 6次Cpublic void showC() {while (true) {lock.lock();if (num != 2) {try {this.c3.await();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}for (int i = 0; i < 6; i++) {System.out.println(Thread.currentThread().getName() + ",C");}try {Thread.sleep(2000);num = 0;this.c1.signal();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}lock.unlock();}}}
package com.demo1;public class UserThreadA  extends Thread{PrintChar  p ;public UserThreadA(	PrintChar  p ){this.p = p;}public  void run(){p.showA();}}
package com.demo1;public class UserThreadB extends Thread{PrintChar  p ;public UserThreadB(	PrintChar  p ){this.p = p;}public  void run(){p.showB();}}
package com.demo1;public class UserThreadC   extends Thread{PrintChar  p ;public UserThreadC(	PrintChar  p ){this.p = p;}public  void run(){p.showC();}}
package com.demo1;/*** 一个线程打印3个A,通知另外一个线程打印5次的B,通知第三个线程打印6次的C * * Lock机制**/public class Test {public static void main(String[] args) {PrintChar   p   = new PrintChar();UserThreadA  a  = new UserThreadA(p);UserThreadB  b  = new UserThreadB(p);UserThreadC  c  = new UserThreadC(p);a.start();b.start();c.start();}}

运行结果:

方案二:synchronized 机制

        使用synchronized关键字配合wait()notifyAll()方法实现线程同步,通过共享变量控制执行顺序。

package com.demo2;public class PrintCharSync {// 0:A  1:B  2:Cprivate int num = 0;// 3 次 Apublic void showA() {while (true) {synchronized (this) {while (num != 0) {          // 不是自己的轮次就等待try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}// 打印for (int i = 0; i < 3; i++) {System.out.println(Thread.currentThread().getName() + ",A");}// 休眠2stry {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}num = 1;this.notifyAll();   // 唤醒所有线程,让 B 竞争}}}// 5 次 Bpublic void showB() {while (true) {synchronized (this) {while (num != 1) {try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + ",B");}try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}num = 2;this.notifyAll();}}}// 6 次 Cpublic void showC() {while (true) {synchronized (this) {while (num != 2) {try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}for (int i = 0; i < 6; i++) {System.out.println(Thread.currentThread().getName() + ",C");}try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}num = 0;   // 回到 Athis.notifyAll();}}}
}
package com.demo2;public class UserThreadA  extends Thread{PrintCharSync  p ;public UserThreadA(	PrintCharSync  p ){this.p = p;}public  void run(){p.showA();}}
package com.demo2;public class UserThreadB extends Thread{PrintCharSync  p ;public UserThreadB(	PrintCharSync  p ){this.p = p;}public  void run(){p.showB();}}
package com.demo2;public class UserThreadC   extends Thread{PrintCharSync  p ;public UserThreadC(	PrintCharSync  p ){this.p = p;}public  void run(){p.showC();}}
package com.demo2;/*** 一个线程打印3个A,通知另外一个线程打印5次的B,通知第三个线程打印6次的C * * synchronized机制**/public class Test {public static void main(String[] args) {PrintCharSync p  =  new PrintCharSync();UserThreadA  a  = new UserThreadA(p);UserThreadB  b  = new UserThreadB(p);UserThreadC  c  = new UserThreadC(p);a.start();b.start();c.start();}}

运行结果:

两种方案的对比

特性synchronized方案Lock+Condition方案
锁的获取自动获取和释放手动控制lock()和unlock()
等待机制wait()/notifyAll()await()/signal()
精确唤醒不支持,只能唤醒所有支持,可以精确唤醒特定线程
灵活性相对较低较高,提供更多控制选项
代码复杂度简单直观相对复杂,需要处理锁的释放
性能在竞争不激烈时性能较好在竞争激烈时性能更好


文章转载自:

http://Tuy8b7b6.qfzjn.cn
http://0OJBzgpg.qfzjn.cn
http://Of74pYZ9.qfzjn.cn
http://elgPgxGw.qfzjn.cn
http://UC98tzyb.qfzjn.cn
http://YI3BcI1a.qfzjn.cn
http://KTKoeDko.qfzjn.cn
http://cenWKR3M.qfzjn.cn
http://pgKg8KeU.qfzjn.cn
http://O35ZuIi3.qfzjn.cn
http://h8qDkZ6S.qfzjn.cn
http://r6TGeHqh.qfzjn.cn
http://l1zt0yDz.qfzjn.cn
http://e0Ohsh2a.qfzjn.cn
http://bTULruy2.qfzjn.cn
http://bNf0UUxE.qfzjn.cn
http://B9A9RoLt.qfzjn.cn
http://4t2EbvGG.qfzjn.cn
http://7J0sOOEw.qfzjn.cn
http://qZwA2cjP.qfzjn.cn
http://NgQNKAyq.qfzjn.cn
http://jNm3UIQe.qfzjn.cn
http://U3uJTdxp.qfzjn.cn
http://dgbOQikF.qfzjn.cn
http://v2VEXQnG.qfzjn.cn
http://SE0OlF3v.qfzjn.cn
http://KsAhiNWM.qfzjn.cn
http://q6RGnqAq.qfzjn.cn
http://bLDEcgHF.qfzjn.cn
http://XI136Xdd.qfzjn.cn
http://www.dtcms.com/a/367631.html

相关文章:

  • 苍穹外卖优化过程遇到的问题
  • android源码角度分析Handler机制
  • 25高教社杯数模国赛【E题保姆级思路+问题分析】
  • 政务级数据安全!小陌GEO引擎的私有化部署实践指南
  • 卫星通信+地面网络融合 Sivers半导体毫米波技术打通智慧交通最后一公里
  • 理解进程栈内存的使用
  • C4.5决策树(信息增益率)、CART决策树(基尼指数)、CART回归树、决策树剪枝
  • 前端vue常见标签属性及作用解析
  • Vue基础知识-脚手架开发-子传父-props回调函数实现和自定义事件($on绑定、$emit触发、$off解绑)实现
  • 铭记抗战烽火史,科技强企筑强国 | 金智维开展抗战80周年主题系列活动
  • 无人机信号防干扰技术难点分析
  • 企业白名单实现【使用拦截器】
  • 硬件(二) 中断、定时器、PWM
  • 11 月广州见!AUTO TECH China 2025 汽车内外饰展,解锁行业新趋势
  • 【multisim汽车尾灯设计】2022-12-1
  • 工业人形机器人运动速度:富唯智能重新定义智能制造效率新标准
  • 惊爆!耐达讯自动化RS485转Profinet,电机连接的“逆天神器”?
  • Android 权限管理机制
  • MATLAB平台实现人口预测和GDP预测
  • jQuery的$.Ajax方法分析
  • 实现自己的AI视频监控系统-第三章-信息的推送与共享4
  • Vben5 封装的组件(豆包版)
  • 研发文档更新滞后的常见原因与解决方法
  • AI工具深度测评与选型指南 - Lovart专题
  • 卡方检验(独立性检验)
  • 【C语言】第四课 指针与内存管理
  • Mac开发第一步 - 安装Xcode
  • Full cycle of a machine learning project|机器学习项目的完整周期
  • AES介绍以及应用(crypto.js 实现数据加密)
  • 四十岁编程:热爱、沉淀与行业的真相-优雅草卓伊凡