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

线程通信机制

目录

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

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.dtcms.com/a/365716.html

相关文章:

  • 记录一下node后端写下载https的文件报错,而浏览器却可以下载。
  • 开源与闭源的再对决:从Grok到中国力量,AI生态走向何方?
  • 并发编程指南 同步操作与强制排序
  • Claude Code初体验:让AI成为你的结对程序员
  • Linux学习——管理基本存储(十八)
  • A股大盘数据-2025093分析
  • Provider中的watch、read、Consumer、ChangeNotifierProvider、ValueNotifierProvider
  • 信息融智学=信息哲学+信息科学+信息技术+信息系统工程+信息处理之智
  • 数据库选择有讲究?SQLite、PostgreSQL还是MySQL?
  • 全渠道 + 低代码:如何打造 “内外协同” 的客服管理系统体系?
  • http和https区别是什么
  • docker 安装 redis 并设置 volumes 并修改 修改密码(三)
  • 【TypeScript】事件循环
  • k8s的SidecarSet配置和initContainers
  • 《四川棒球知识百科》球速最快的运动之一·棒球1号位
  • Omi录屏专家 Screen Recorder Mac中文
  • 如何在私域运营中快速建立信任,三招解决你的烦恼!
  • linux---------------网络基础概念
  • 【IQA技术专题】 无参考自然图像IQA:NIQE
  • 审核问题——一个关于版本号的乌龙事件
  • Elasticsearch面试精讲 Day 6:Query DSL查询语法详解
  • 2025年9月,十大求职神器测评:谁是Offer收割机之王?
  • 玳瑁的嵌入式日记D32-0903(网络编程)
  • Nginx简介
  • 自学嵌入式第三十四天:网络编程-TCP
  • dumpsys alarm 简介
  • Java+AI开发实战与知识点归纳系列:Spring流式输出实战——LangChain4j与Ollama集成
  • Spring Authorization Server 1.5.2 使用YML配置的方式,最常用法总结
  • VAR的教师强制teacher forcing
  • Canaan 阿瓦隆 A1246I 81T矿机评测:性能、功耗与能效全面分析