3.什么是线程间的通信 ?怎么实现线程通信
3.1什么是线程通信以及实现步骤
线程间通信的模型有两种:共享内存和消息传递
线程通信其实就是 ,实现线程的交替工作,并传递信息
线程间的通信具体步骤:(涉及上中下部)
创建资源类,在资源类中船舰属性和操作方法
在资源类操作方法:判断、操作、通知
创建多个线程,调用资源类的操作方法
防止虚拟唤醒问题 (if 判读,只会判断一次)
3.2 synchronized案例
操作线程的时候,等待线程使用wait()
通知另外的线程操作用notify()、notifyAll()
假设有两个线程,该线程在执行过程中,判断值(不是该值等待,让其他线程抢),操作值,通知另外一个线程的调度
实现两个线程 对num 这个值操作,一个线程加1,一个线程减1,交替实现多次
public class ThreadDemo1 {
//第三步 创建多个线程,调用资源类的操作方法
public static void main(String[] args) {
Share share = new Share();
//创建线程
new Thread(()->{
for (int i = 1; i <=10; i++) {
try {
share.incr(); //+1
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"AA").start();
new Thread(()->{
for (int i = 1; i <=10; i++) {
try {
share.decr(); //-1
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"BB").start();
}
}
//第一步 创建资源类,定义属性和操作方法
class Share {
//初始值
private int num = 0;
//+1的方法
public synchronized void incr() throws InterruptedException {
//第二步 判断 干活 通知
if(num != 0) { //判断number值是否是0,如果不是0,等待
this.wait(); //在哪里睡,就在哪里醒
}
//如果number值是0,就+1操作
num++;
System.out.println(Thread.currentThread().getName()+" :: "+num);
//通知其他线程
this.notifyAll(); //注意这里的通知是随机的,就是只能通知全部
}
//-1的方法
public synchronized void decr() throws InterruptedException {
//判断
if(num != 1) {
this.wait();
}
//干活
num--;
System.out.println(Thread.currentThread().getName()+" :: "+num);
//通知其他线程
this.notifyAll();
}
}
可以看到,这时,代码是交替进行的 一个 +1 一个线程 -1
但是我们考虑如果同时 ,分别两个线程做加减,那会怎么样呢?
虚假唤醒 : wait 是在哪里睡,在哪里被唤醒只做了一次判断 虚假唤醒 放在while if 判断,只 会判断一次 所以改为while ;循环判断,就会解决虚假唤醒;从而解决这个错误
3.3 Lock案例
使用lock先要创建锁的对象以及通知的对象
放置在资源类中
private Lock lock= new ReentrantLock(); //创建可重锁
private Condition condition= lock.newCondition();
//他能操作的对象
上锁 lock.lock();
解锁 lock.unlock();
以下都为 condition类:
唤醒所有等待的线程signalAll(),带上类名condition.signalAll();
唤醒一个等待线程signal(),带上类名,condition.signal();
造成当前线程在接到信号或者被中断之前一直处于等待状态await(),带上类名,condition.await();
Lock 实现的代码基本是相同的,注意上锁 和解锁 是自己手动 做的工作,最终都要在finally 解锁
如果不解锁,会影响下面以后的线程
class LShare{
//这是共享资源,注意锁的创建和使用,其他的和上面基本相同
private int num=0;
private Lock lock= new ReentrantLock(); //创建可重锁
private Condition condition= lock.newCondition();
//创建操作的方法
public void add (){
lock.lock(); //首先 手动上锁;
try { //判断,干活,通知
while (num!=0){
condition.await();
//它使用的是这个对象 调用方法 等待
}
num++;
System.out.println( Thread.currentThread().getName()+" 干活完成 :"+num);
condition.signalAll(); //这个通知方法
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock(); //最终不管出现什么错误,都会解锁
}
}
这就实现了线程间的通信,,即 他们能够根据 信息,完成交替的工作
下面就是学如何 定制通信?(交替进行线程,但是每个线程的 工作是改变的)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?