担路网口碑做网站好吗哪里做外贸网站
2026/5/21 12:09:37 网站建设 项目流程
担路网口碑做网站好吗,哪里做外贸网站,系统网站建设ppt,交通建设集团网站文章目录线程间通信的秘密#xff1a;如何让B感知A的变化#xff1f;一、引言#xff1a;为什么线程间通信这么重要#xff1f;二、最简单的“通信”方式#xff1a;共享变量示例代码#xff1a;分析#xff1a;三、解决可见性问题#xff1a;volatile关键字修改后的代…文章目录线程间通信的秘密如何让B感知A的变化一、引言为什么线程间通信这么重要二、最简单的“通信”方式共享变量示例代码分析三、解决可见性问题volatile关键字修改后的代码分析四、高级的通信机制wait和notify示例代码分析五、生产者-消费者模式示例代码分析六、总结希望这篇总结能帮助你更好地理解线程间通信的各种方法 领取 | 1000 套高质量面试题大合集无套路闫工带你飞一把线程间通信的秘密如何让B感知A的变化大家好我是闫工今天咱们要聊一个看似简单但其实非常重要的问题——线程间通信。这个问题在多线程编程中几乎无处不在尤其是在并发场景下如何让线程B感知到线程A的状态变化是一个必须要解决的问题。可能有的同学会觉得“不就是线程之间共享变量吗直接用一个全局变量不就行了”但事实并非如此简单。线程间通信不仅仅是简单的数据共享还需要考虑线程安全、内存可见性等问题。今天咱们就从这个问题入手一步步深入探讨如何让线程B感知到线程A的变化。一、引言为什么线程间通信这么重要在Java中多线程编程的核心目标之一就是提高程序的执行效率。多个线程可以同时执行不同的任务从而充分利用 CPU 的资源。然而在实际开发中线程之间往往需要协作比如一个线程完成某个计算后另一个线程才能继续处理结果。举个简单的例子假设线程A负责从数据库读取数据线程B负责对这些数据进行处理。如果线程A没有读完数据线程B就开始处理那就会出问题。因此我们需要一种机制让线程B知道线程A已经完成了任务。这就是线程间通信的核心——如何通知其他线程自己状态的变化。接下来咱们就从简单到复杂一步步探讨这个问题的解决方法。二、最简单的“通信”方式共享变量在Java中线程之间可以通过共享变量来进行通信。比如可以定义一个全局变量flag当线程A完成任务后将flag设置为true然后线程B就可以通过检查这个flag来判断是否可以继续执行。示例代码publicclassSharedVariableExample{// 共享变量privatestaticbooleanflagfalse;publicstaticvoidmain(String[]args){ThreadthreadAnewThread(()-{try{System.out.println(线程A开始工作...);Thread.sleep(2000);// 模拟耗时操作flagtrue;System.out.println(线程A完成任务flag设置为true);}catch(InterruptedExceptione){e.printStackTrace();}});ThreadthreadBnewThread(()-{while(!flag){// 等待线程A完成任务System.out.println(线程B在等待...);try{Thread.sleep(500);}catch(InterruptedExceptione){e.printStackTrace();}}System.out.println(线程B感知到变化开始处理...);});threadA.start();threadB.start();}}分析共享变量flag是一个全局变量两个线程都可以访问它。线程A的任务完成耗时操作后设置flag为true。线程B的任务循环检查flag直到flag变为true。这种方法看起来简单但在实际应用中存在一个大问题——不可见性。由于Java的内存模型允许多个线程有自己的缓存副本如果线程A修改了flag线程B可能看不到这个变化从而导致死循环或其他异常行为。三、解决可见性问题volatile关键字为了保证共享变量的变化对其他线程可见我们可以使用volatile关键字。volatile告诉JVM这个变量不会被缓存每次读取时都会从主内存中获取最新的值。修改后的代码publicclassVolatileExample{privatestaticvolatilebooleanflagfalse;publicstaticvoidmain(String[]args){ThreadthreadAnewThread(()-{try{System.out.println(线程A开始工作...);Thread.sleep(2000);// 模拟耗时操作flagtrue;System.out.println(线程A完成任务flag设置为true);}catch(InterruptedExceptione){e.printStackTrace();}});ThreadthreadBnewThread(()-{while(!flag){// 等待线程A完成任务System.out.println(线程B在等待...);try{Thread.sleep(500);}catch(InterruptedExceptione){e.printStackTrace();}}System.out.println(线程B感知到变化开始处理...);});threadA.start();threadB.start();}}分析volatile关键字通过volatile修饰flag确保了每个线程都能看到最新的值。优点简单、高效。缺点仅适用于简单的共享变量无法处理更复杂的通信需求。四、高级的通信机制wait和notify在Java中Object类提供了wait()和notify()方法用于线程间的同步。这两个方法通常与synchronized关键字结合使用可以实现生产者-消费者模式。示例代码publicclassWaitNotifyExample{privatestaticfinalObjectlocknewObject();privatestaticbooleanflagfalse;publicstaticvoidmain(String[]args){ThreadthreadAnewThread(()-{try{System.out.println(线程A开始工作...);Thread.sleep(2000);// 模拟耗时操作synchronized(lock){flagtrue;lock.notify();// 通知其他线程System.out.println(线程A完成任务flag设置为true);}}catch(InterruptedExceptione){e.printStackTrace();}});ThreadthreadBnewThread(()-{synchronized(lock){while(!flag){try{System.out.println(线程B在等待...);lock.wait();// 等待通知}catch(InterruptedExceptione){e.printStackTrace();}}System.out.println(线程B感知到变化开始处理...);}});threadA.start();threadB.start();}}分析synchronized关键字用于同步代码块保证同一时间只有一个线程可以执行。wait()方法让当前线程进入等待状态并释放锁。notify()方法唤醒一个正在等待的线程。优点支持更复杂的通信逻辑且能避免“忙等待”即不断轮询的问题。缺点代码相对复杂需要手动管理锁。五、生产者-消费者模式生产者-消费者模式是线程间通信的一个典型应用场景。一个线程负责生产数据生产者另一个线程负责消费数据消费者。当数据准备好后生产者通知消费者可以开始处理。示例代码importjava.util.Queue;importjava.util.concurrent.ConcurrentLinkedQueue;publicclassProducerConsumerExample{privatestaticQueueIntegerqueuenewConcurrentLinkedQueue();privatestaticfinalObjectlocknewObject();privatestaticbooleandonefalse;publicstaticvoidmain(String[]args){ThreadproducernewThread(()-{try{System.out.println(生产者开始工作...);Thread.sleep(2000);// 模拟生产时间queue.add(123);synchronized(lock){donetrue;lock.notify();System.out.println(生产者完成数据已放入队列);}}catch(InterruptedExceptione){e.printStackTrace();}});ThreadconsumernewThread(()-{synchronized(lock){while(!done){try{System.out.println(消费者在等待...);lock.wait();}catch(InterruptedExceptione){e.printStackTrace();}}intdataqueue.poll();System.out.println(消费者获取数据data);}});producer.start();consumer.start();}}分析生产者将数据放入队列后设置done为true并通知消费者。消费者等待直到done变为true然后从队列中获取数据。优点支持高并发场景代码结构清晰。六、总结如果只需要简单的共享变量同步可以使用volatile关键字。对于更复杂的通信需求推荐使用wait()和notify()方法或者直接采用生产者-消费者模式。在实际开发中还可以考虑使用Java并发包中的高级工具类如CountDownLatch、CyclicBarrier等以简化代码逻辑。希望这篇总结能帮助你更好地理解线程间通信的各种方法 领取 | 1000 套高质量面试题大合集无套路闫工带你飞一把成体系的面试题无论你是大佬还是小白都需要一套JAVA体系的面试题我已经上岸了你也想上岸吗闫工精心准备了程序准备面试想系统提升技术实力闫工精心整理了1000 套涵盖前端、后端、算法、数据库、操作系统、网络、设计模式等方向的面试真题 详细解析并附赠高频考点总结、简历模板、面经合集等实用资料✅ 覆盖大厂高频题型✅ 按知识点分类查漏补缺超方便✅ 持续更新助你拿下心仪 Offer免费领取 点击这里获取资料已帮助数千位开发者成功上岸下一个就是你✨

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询