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

线程通信机制

目录

一、主线程与子线程基础通信

1.1 主线程向子线程传递数据

二、子线程向主线程返回数据

2.1 通过共享变量方式

2.2 同步块中使用wait/notify机制

2.3 Lock和Condition实现线程通信机制


一、主线程与子线程基础通信

1.1 主线程向子线程传递数据

  • 通过构造函数传递参数:主线程通过UserThread的构造函数将数据a传递给子线程

package com.demo6;public class Test {public static void main(String[] args) {System.out.println(Thread.currentThread().getName()+",主线程");int  a  = 10;UserThread  u  = new UserThread(a);u.start();}
}
package com.demo6;public class UserThread  extends Thread{int  a  ;public UserThread(int a){this.a  = a;}public void  run(){System.out.println(Thread.currentThread().getName()+",执行run方法"+",a的值为:"+a);}}
  • 输出结果:主线程创建子线程后,子线程输出接收到的参数值

二、子线程向主线程返回数据

2.1 通过共享变量方式

  • sleep等待:主线程通过sleep等待子线程完成计算

  • 共享变量:子线程将计算结果存储在成员变量中,主线程通过getter方法获取

  • 缺点:sleep时间难以精确控制,可能等待过长或过短

package com.demo7;public class Test {public static void main(String[] args) {UserThread ut  =new UserThread();ut.start();try {Thread.sleep(5*1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("主线程通过getter方法获取的值为: "+ut.getSum());}}
package com.demo7;public class UserThread   extends Thread{private int sum = 0;public void  run(){for(int i=0;i<=100;i++){this.sum +=i;}}public int  getSum(){return this.sum;}}

运行结果:

2.2 同步块中使用wait/notify机制

  • 同步协作:主线程和子线程使用同一个对象锁进行同步

  • wait/notify机制:主线程等待,子线程完成后通知主线程

(1)当主线程持有的是当前线程类对象的锁,如果是当前线程类对象的自己this和父类(Object/Thread.class/接口父类.class),都可以通知解锁。 都可以显示的或隐式的写notify。

package com.demo13;public class Test {public static void main(String[] args) {UserThread u = new UserThread();u.start();//线程通信的必须的条件是:同一个对象//如果持有的是当前线程类对象的锁,如果是当前线程类对象的自己this和父类,都可以通知解锁//都可以显示的或隐式的写notifysynchronized (u) {try {//主线程持有u对象的锁,被阻塞u.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("主线程获取的值为:"+u.getSum());}}}
package com.demo13;public class UserThread   extends Thread  implements IUser{private int  sum = 0;Object  obj  = new Object();public void run(){//		synchronized (this) {
//			for(int i=0;i<=100; i++)
//			{
//				sum+=i;
//			}
//		this.notify();
//		}//		synchronized (Thread.class) {
//			for(int i=0;i<=100; i++)
//			{
//				sum+=i;
//			}
//		}//		synchronized (obj) {
//			for(int i=0;i<=100; i++)
//			{
//				sum+=i;
//			}
//		}synchronized (IUser.class) {for(int i=0;i<=100; i++){sum+=i;}}}public  int getSum(){return this.sum;}}
package com.demo13;public interface IUser {}

运行结果:

(2)当主线程持有的是非线程类对象的锁,子线程持有的也只能是非线程类对象的锁。这是只能显示的写notify。

package com.demo13;public class Test {public static void main(String[] args) {User  u1  =  new User();UserThread   u = new UserThread(u1);u.start();synchronized (u1) {try {//主线程持有u1对象的锁,内阻塞u1.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("主线程获取的值为:"+u.getSum());}}}
package com.demo13;public class UserThread   extends Thread  implements IUser{private int  sum = 0;User  u1;public UserThread(User u1) {this.u1 = u1;}public void run(){synchronized (u1) {for(int i=0;i<=100; i++){sum+=i;}//显示解锁u1.notify();}}public  int getSum(){return this.sum;}}
package com.demo13;public class User {}

运行结果:

如果子线程又new了User类对象u1,此时主线程和子线程的u1不是同一个对象,会发生死锁:

2.3 Lock和Condition实现线程通信机制

        这是一种基于明锁(Lock)和条件变量(Condition)的线程通信机制,属于JUC包中的高级同步机制。

     工作流程:

  1. 创建锁和条件:主线程创建ReentrantLock和Condition对象

  2. 传递资源:将锁和条件传递给子线程

  3. 主线程等待:主线程获取锁后调用cond.await()进入等待状态

  4. 子线程执行:子线程获取锁,执行计算任务

  5. 发送信号:子线程完成任务后调用cond.signal()唤醒主线程

  6. 结果获取:主线程被唤醒后获取并输出计算结果

package com.demo31;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class Test {public static void main(String[] args) {Lock  lock  = new ReentrantLock();// 通过锁创建条件变量Condition cond  =lock.newCondition();UserThread  u1  =  new UserThread(lock,cond);u1.start();lock.lock();try {// 主线程等待条件信号cond.await();// 收到信号后输出计算结果System.out.println(u1.getSum());} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}// 手动释放锁lock.unlock();}}
package com.demo31;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;public class UserThread extends Thread {private Lock lock;private int sum;private Condition cond;public UserThread(Lock lock,Condition cond) {this.lock = lock;this.cond  =cond;}public void run() {lock.lock();for (int i = 0; i <= 100; i++) {try {Thread.sleep(200);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}this.sum += i;}// 发送条件信号,唤醒等待的线程this.cond.signal();// 释放锁this.lock.unlock();}public  int getSum(){return  this.sum;}}

运行结果:

http://www.xdnf.cn/news/19820.html

相关文章:

  • 【程序人生】有梦想就能了不起,就怕你没梦想
  • BurpSuite_Pro_V2024.6使用教程-Burp Suite代理设置详解
  • (Me)Adobe Media Encoder 2025音视频格式转码软件及视频编码软件,全新版免激活,安装即永久使用!
  • HTTP协议——理解相关概念、模拟实现浏览器访问自定义服务器
  • 优化程序性能 | 《深入理解计算机系统》第五章笔记
  • React实现列表拖拽排序
  • LiteFlow:国产流程编排引擎体验
  • DAY20-新世纪DL(DeepLearning/深度学习)战士:终(目标检测/YOLO)3
  • 【医疗行业案例】基于 React 的预约系统:DHTMLX 助力高效排班与预约管理
  • CAD/BIM软件产品技术深度分析文章写作计划
  • 全渠道 + 低代码:如何打造 “内外协同” 的客服管理系统体系?
  • 【FastDDS】Layer DDS之Domain ( 02-DomainParticipant )
  • unity中的交互控制脚本
  • 云手机将要面临的挑战有哪些?
  • 【学习记录】github私人仓库创建和本地克隆
  • CSS 伪类与伪元素:深度解析
  • 从零构建Linux Shell解释器深入理解Bash进程创建机制
  • 【Spring Cloud微服务】11.微服务通信演义:从飞鸽传书到5G全息,一部消息中间件的进化史诗
  • Java项目打包成EXE全攻略​
  • Ubuntu22.04下编译googletest源代码生成.so动态库
  • 利用 openssl api 实现 TLS 双向认证
  • MySQL-MVCC多版本并发控制详解
  • LangChain实战(十二):自定义Tools扩展Agent能力
  • Python+DRVT 从外部调用 Revit:批量创建门
  • Streamable HTTP
  • sv中forever如何结束
  • AI 在金融、医疗、教育、制造业等领域有着广泛的应用,以下是这些领域的一些落地案例
  • STM32HAL 快速入门(十七):UART 硬件结构 —— 从寄存器到数据收发流程
  • 告别剪辑烦恼!3个超实用技巧,让你的视频瞬间高级起来
  • 【音视频】视频秒播优化实践