JAVA5多线程---Condition使用---线程通信

深入理解Java线程通信:5种核心方法详解与实战代码 在多线程编程中,线程通信是协调多个线程有序工作、避免资源竞争的关键技术。当多个线程需要协同完成某个任务时,比如经典的生产者-消费者模型,就需要通过高效的通信机制来实现数据的安全传递和任务协调。:通过Object类的wait()让线程等待,notify()/notifyAll()唤醒等待线程。Condition对象通过Lock.newCondition()创建。:更细粒度的线程控制,支持多个等待条件队列。notifyAll()唤醒所有等待线程。signal()唤醒单个等待线程。put()在队列满时自动阻塞。 阅读详情


分类: JAVA基础 70人阅读 评论(2) 收藏 举报

             线程之间除了同步互斥,还要考虑通信。在Java5之前我们的通信方式为:wait 和 notify。那么Condition的优势是支持多路等待,就是我可以定义多个Condition,每个condition控制线程的一条执行通路。传统方式只能是一路等待。我们可以先分析下Java5 Api中的缓冲队列的实现:

        假定有一个绑定的缓冲区,它支持 put 和 take 方法。如果试图在空的缓冲区上执行take 操作,则在某一个项变得可用之前,线程将一直阻塞;如果试图在满的缓冲区上执行put 操作,则在有空间变得可用之前,线程将一直阻塞。我们喜欢在单独的等待 set 中保存put 线程和take 线程,这样就可以在缓冲区中的项或空间变得可用时利用最佳规划,一次只通知一个线程。可以使用两个Condition 实例来做到这一点。

  1. class BoundedBuffer {  
  2.            final Lock lock = new ReentrantLock();//实例化一个锁对象  
  3.            final Condition notFull  = lock.newCondition(); //实例化两个condition  
  4.            final Condition notEmpty = lock.newCondition();   
  5.   
  6.            final Object[] items = new Object[100];//初始化一个长度为100的队列  
  7.            int putptr, takeptr, count;  
  8.   
  9.            public void put(Object x) throws InterruptedException {  
  10.              lock.lock();//获取锁  
  11.              try {  
  12.                while (count == items.length)   
  13.                  notFull.await();//当计数器count等于队列的长度时,不能在插入,因此等待  
  14.                items[putptr] = x; //将对象放入putptr索引处  
  15.                if (++putptr == items.length) putptr = 0;//当索引长度等于队列长度时,将putptr置为0  
  16.                //原因是,不能越界插入  
  17.                ++count;//没放入一个对象就将计数器加1  
  18.                notEmpty.signal();//一旦插入就唤醒取数据线程  
  19.              } finally {  
  20.                lock.unlock();//最后释放锁  
  21.              }  
  22.            }  
  23.   
  24.            public Object take() throws InterruptedException {  
  25.              lock.lock();//获取锁  
  26.              try {  
  27.                while (count == 0) //如果计数器等于0那么等待  
  28.                  notEmpty.await();  
  29.                Object x = items[takeptr]; //取得takeptr索引处对象  
  30.                if (++takeptr == items.length) takeptr = 0;//当takeptr达到队列长度时,从零开始取  
  31.                --count;//每取一个讲计数器减1  
  32.                notFull.signal();//枚取走一个就唤醒存线程  
  33.                return x;  
  34.              } finally {  
  35.                lock.unlock();//释放锁  
  36.              }  
  37.            }   
  38.          }  

下面还有一个例子:

启动main,sub2,sub3三个线程,sub2运行完后sub3运行,sub3运行完成后main运行,main运行完成后sub2运行,如此循环往复50次。实现代码如下:

  1. import java.util.concurrent.locks.Condition;  
  2. import java.util.concurrent.locks.Lock;  
  3. import java.util.concurrent.locks.ReentrantLock;  
  4.   
  5. public class ConditionCommunication {  
  6.   
  7.     /** 
  8.      * @param args 
  9.      */  
  10.     public static void main(String[] args) {  
  11.           
  12.         final Business business = new Business();  
  13.           
  14.         new Thread(new Runnable(){  
  15.   
  16.             public void run() {  
  17.                 for(int i=0; i<50; i++){  
  18.                     business.sub2(i);  
  19.                 }  
  20.             }  
  21.               
  22.         }).start();  
  23.           
  24.         new Thread(new Runnable(){  
  25.   
  26.             public void run() {  
  27.                 for(int i=0; i<50; i++){  
  28.                     business.sub3(i);  
  29.                 }  
  30.             }  
  31.               
  32.         }).start();  
  33.           
  34.           
  35.         new Thread(new Runnable(){  
  36.   
  37.             public void run() {  
  38.                 for(int i=0; i<50; i++){  
  39.                     business.main(i);  
  40.                 }  
  41.             }  
  42.               
  43.         }).start();  
  44.           
  45.     }  
  46.       
  47.       
  48.       
  49.     static class Business{  
  50.           
  51.         private int shouldSub = 1;  
  52.           
  53.         private Lock lock = new ReentrantLock();  
  54.           
  55.         Condition condition1 = lock.newCondition();  
  56.           
  57.         Condition condition2 = lock.newCondition();  
  58.           
  59.         Condition condition3 = lock.newCondition();  
  60.           
  61.           
  62.         public void sub2(int i){  
  63.             try{  
  64.                 lock.lock();  
  65.                 while(shouldSub != 2){  
  66.                     try {  
  67.     //                  this.wait();  
  68.                         condition2.await();  
  69.                     } catch (Exception e) {  
  70.                         e.printStackTrace();  
  71.                     }  
  72.                 }  
  73.                 for(int j=1; j<=10; j++){  
  74.                     System.out.println("sub2 thread sequence is " + j + " loop of " + i);  
  75.                 }  
  76.                 shouldSub = 3;  
  77.     //          this.notify();  
  78.                 condition3.signal();  
  79.             }finally{  
  80.                 lock.unlock();  
  81.             }  
  82.         }  
  83.           
  84.           
  85.         public void sub3(int i){  
  86.             try{  
  87.                 lock.lock();  
  88.                 while(shouldSub != 3){  
  89.                     try {  
  90.     //                  this.wait();  
  91.                         condition3.await();  
  92.                     } catch (Exception e) {  
  93.                         e.printStackTrace();  
  94.                     }  
  95.                 }  
  96.                 for(int j=1; j<=20; j++){  
  97.                     System.out.println("sub3 thread sequence is " + j + " loop of " + i);  
  98.                 }  
  99.                 shouldSub = 1;  
  100.     //          this.notify();  
  101.                 condition1.signal();  
  102.             }finally{  
  103.                 lock.unlock();  
  104.             }  
  105.         }  
  106.           
  107.           
  108.           
  109.         public void main(int i){  
  110.             try{  
  111.                 lock.lock();  
  112.                 while(shouldSub != 1){  
  113.                     try {  
  114. //                      this.wait();  
  115.                         condition1.await();  
  116.                     } catch (Exception e) {  
  117.                         e.printStackTrace();  
  118.                     }  
  119.                 }  
  120.                 for(int j=1; j<=100; j++){  
  121.                     System.out.println("main thread sequence is " + j + " loop of " + i);  
  122.                 }  
  123.                 shouldSub = 2;  
  124. //              this.notify();  
  125.                 condition2.signal();  
  126.             }finally{  
  127.                 lock.unlock();  
  128.             }  
  129.         }  
  130.     }  
  131.   
  132. } 

PLC集群管理:C#上位机实现10台以上分布式PLC的集中监控与指令下发 本文介绍了一套基于C# WPF开发的PLC集群管理系统,用于解决现代工业自动化产线中分布式PLC监控难题。系统采用三层解耦架构,支持100台以内不同品牌PLC的集中管理,具备批量数据采集、指令下发、实时报警等功能。核心创新点包括:1)基于异步IO的连接池管理;2)统一通信接口设计;3)寄存器合并优化算法;4)三级优先级指令队列。实际应用表明,系统数据采集延迟低于100ms,指令下发成功率99.9%,有效解决了传统单PLC监控模式存在的效率低下问题。 阅读详情

相关推荐

七星棋牌顶级运营产品全开源修复版源码教程:6端支持,200+子游戏玩法,完整搭建指南(含代码解析)

让您从源码下载到本地运行一步到位!此外,文中还将附带详细代码解析与操作步骤,即便没有开发经验,也能轻松完成二开与定制。数据库是棋牌游戏中极为关键的组成部分,用于存储用户信息、乐豆余额、游戏记录、提现申请等数据。以下是部分核心数据表结构示例,便于存储用户信息与游戏记录。AI模块能够控制游戏中的胜率,常用于调节玩家体验。防沉迷功能旨在限制未成年人游戏时间。的完整搭建流程,特别适合。首先,获取七星棋牌源码。本教程将为您详细讲解。

aa2031171的博客 7781

Java线程(八):Condition-线程通信更高效的方式

上一篇讲述了并发包下的Lock,Lock可以更好的解决线程同步问题,使之更面向对象,并且ReadWriteLock在处理同步时更强大,那么同样,线程间仅仅互斥是不够的,还需要通信,本篇的内容是基于上篇之上,使用Lock如何处理线程通信。         那么引入本篇的主角,Condition,Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分

且听风吟的专栏 2052

百度无人车ApolloAuto使用入门

1.安装原版ubuntu 14.04 http://www.ubuntu.org.cn/download/alternative-downloads 2.安装对应ubuntu 14.04的indigo版ROS http://wiki.ros.org/indigo/Installation/Ubuntu 3.安装Apollo Kernel https://github.co

ss910的博客 3万+

Java并发编程(2)--锁的用法

一.synchronized关键字 synchronized是java中的一个关键字,也就是说是Java语言内置的特性。如果一个代码块被synchronized修饰了,当一个线程获取了对应的锁,并执行该代码块时,其他线程便只能一直等待,等待获取锁的线程释放锁,而这里获取锁的线程释放锁只会有两...

chuigufu8581的博客 201

Security Onion的部署(超详细)

本文介绍了开源入侵检测系统securityonion的部署

qq_72583325的博客 6070

深入解析MTK DRM初始化流程:从KMS模块到组件框架

本文深入解析了联发科(MTK)平台上DRM显示框架的初始化流程。从内核模块加载、Component框架管理依赖,到核心的mtk_drm_bind函数构建KMS对象(CRTC、Plane、Encoder、Connector),最终完成DRM设备注册并创建用户空间接口。文章结合调试经验,为开发者梳理了从驱动启动到屏幕点亮的完整路径与关键排查点。

onion的博客 767

java多线程 锁和Condition总结

注意:本文参考 java并发编程的艺术 从ReentrantLock的实现看AQS的原理及应用 | JavaGuide 重入锁ReentrantLock ReentrantLock简介 重入锁ReentrantLock, 顾名思义,就是支持重进入的锁,它表示该锁能够支持一个线程对 资源的重复加锁。除此之外,该锁的还支持获取锁时的公平和非公平性选择。 回忆在同步器一节中的示例(Mutex), 同时考虑如下场景当一个线程调用Mutex的lock() 方法获取锁之后,如果再次调用lock()方法...

今天吃了吗的博客 1813

ROS激光雷达动态避障算法优化(C++实战)

本文深入探讨了ROS激光雷达动态避障算法的C++实战优化。针对动态环境的核心挑战,文章系统性地介绍了从激光数据预处理(降噪、瘦身)、动态障碍物检测与跟踪,到基于动态窗口法(DWA)的智能决策与调优的全流程。重点分享了如何将障碍物速度预测融入DWA打分函数,以实现更安全、流畅的避障,并提供了工程架构、性能优化及真机调试的实用建议。

weixin_29192141的博客 945

java多线程之Condition的使用

目录 一、Condition的概念 二、Condition的实现分析 (1)等待 (2)通知 三、Condition应用 (1)简单demo (2)可阻塞队列的应用案例 (3)多线程轮流执行 一、Condition的概念 回忆 synchronized 关键字,它配合 Object 的 wait()、notify() 系列方法可以实现等待/通知模式。对于 Lock,通过...

心猿意碼 1万+

从原理到调试:手把手教你用Matlab解码互补格雷码与相移码(附数据与常见错误排查)

本文详细介绍了如何使用Matlab解码互补格雷码与相移码,涵盖从原理到调试的全过程。通过实际案例和代码示例,帮助读者掌握结构光三维重建中的相位解包裹技术,并提供了常见错误排查与优化建议,提升解码效率与准确性。

weixin_29090917的博客 219

基于YOLOv5的仪表读数识别系统:从检测到识别的完整解决方案

随着工业自动化水平的不断提高,仪表读数识别技术在电力系统、石油化工、智能制造等领域发挥着越来越重要的作用。本文提出了一种基于YOLOv5的仪表自动读数识别系统,该系统能够有效区分指针式和数字式仪表,并实现高精度的读数识别。我们详细介绍了系统的整体架构、数据集构建、模型训练策略以及用户界面设计,并提供了完整的代码实现。实验结果表明,本系统在仪表检测和读数识别任务上均取得了优异的表现,为工业现场的自动化监控提供了可靠的技术支持。关键词:仪表读数识别;YOLOv5;目标检测;深度学习;工业自动化。

YOLO 678

JAVA5多线程---Condition使用---线程通信 --wait及notify方法

JAVA5多线程---Condition使用---线程通信   线程之间除了同步互斥,还要考虑通信。在Java5之前我们的通信方式为:wait 和 notify。那么Condition的优势是支持多路等待,就是我可以定义多个Condition,每个condition控制线程的一条执行通路。传统方式只能是一路等待。我们可以先分析下Java5 Api中的缓冲队列的实现: 假定有一

wguoyong的专栏 1628

星敏感器:卫星姿态测量的“星空导航仪”

在卫星、航天器和深空探测器的姿态控制系统中,星敏感器(Star Tracker) 是最精确的姿态测量设备之一。它通过识别恒星的位置,计算出航天器在惯性空间中的三轴姿态,精度可达 角秒级(arcsecond),是许多高精度任务(如遥感、天文观测、深空探测)的核心传感器。

ScilogyHunter的博客 3697

Java多线程编程---线程同步与通信技术(Lock & Condition)

Java5的条件阻塞条件        条件的功能类似在传统线程技术中的的Object.wait()和Object.natify()的功能,传统线程技术实现的互斥只能一个线程单独执行,不能说这个线程执行完了通知另一个线程来执行,条件就是解决这个问题的,实现线程间的通信。比如CPU让线程1做事,线程1说我先歇着并通知线程2,线程2就开始做事。        公共接口条件        条件将对象监视...

知行流浪 627

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Java线程 — 线程的通信 — 使用Lock和Condition接口

wait和notify方法,只能被同步监听锁对象来调用,否则报错。 那么问题来了,Lock机制根本就没有同步锁了,也就没有自动获取锁和自动释放锁的概念。 因为没有同步锁,所以Lock机制不能调用wait和notify方法。 解决方案:java5中提供了Lovk机智的同时提供了处理Lock机制的通信控制的Condition接口。 从java5开始,可以: 1.使用Lock机制取代sy...

weixin_30443731的博客 155

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

【多线程】多线程间的5种通信方式

可别再说不出来多线程间的5种通信方式了 目录 可别再说不出来多线程间的5种通信方式了 问题一、使用 volatile 关键字二、使用 Object 类的 wait()/notify()三、使用JUC工具类 CountDownLatch四、使用 ReentrantLock 结合 Condition五、基本 LockSupport 实现线程间的阻塞和唤醒 有两个线程,A 线程向一个集合里面依次添加元素“abc”字符串,一共添加十次,当添加到第五次的时候,希望 B 线

小源的成长历程 1219

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Java基础——Java重点基础之多线程(二)

一,单例设计模式 单例设计模式:保证类在内存中只有一个对象。 如何保证类在内存中只有一个对象呢? (1)控制类的创建,不让其他类来创建本类的对象。private(2)在本类中定义一个本类的对象。Singleton s;(3)提供公共的访问方式。 public static

梦想家Eva的专栏 361

Java5 多线程(三)--Lock和Condition实现线程同步通信

原文地址:http://blog.youkuaiyun.com/johnny901114/article/details/8695708   1>Lock:          Lock比传统线程模型中的Synchronied方式更加面向对象,与生活中的锁类似,锁本身也应该是一个对象.两个线程执行的代码段要实现同步互斥的效果,它们必须用同一个Lock对象,锁是在代表要操作的资源的类的内部方法中,而不是线

662

JAVA基础——多线程(二)计时器,多线程之间的通信,线程组,线程池的概念

一、 单例设计模式 单例设计模式:保证类在内存中只有一个对象。 如何保证类在内存中只有一个对象呢? (1)控制类的创建,不让其他类来创建本类的对象。也就是让构造方法私有化。 private (2)在本类中定义一个本类的对象。 Singleton s; (3)提供公共的访问方式。 public static Singleton getInstance(){return s} 单例写法两种: (1)饿汉式 开发用这种方式。 public static void main(String[] args) {

Mr_GYF的博客 423

黑马程序员_java多线程学习总结

java 多线程学习总结  多线程技术大大提高了软件程序的效率,尤其是当程序需要与硬件交互时。现在的软件产品越来越重视用户体验,而软件产品的执行效率直接决定了用户体验的好坏。  对多线程的学习需要了解以下几个概念。  进程:    是一个正在执行的程序,每个进程都有执行顺序。该顺序是一个执行路径或一个控制单元。 线程:就是进程中的控制单元,线程控制着进程的执行。一个进程至少包含一个线程。

javamu的专栏 1023

2018.11.21 多线程2(单例,线程通信,互斥锁)

一、单例设计模式 保证类在内存中只有一个对象 如何保证类在内存中只有一个对象呢? (1)控制类的创建,不让其它类来创建本类的对象。private。 (2)在本类中定义一个本类的对象。Singleton s; (3)提供公共的访问方式, public static Singleton getInstance(){ return s } (1)饿汉式····平时开发用 class Singleton...

有文化的博客 144

黑马程序员——5.多线程

Java多线程

u012126525的专栏 439

《疯狂java讲义》第16章 多线程

本章将会详细介绍Java多线程编程的相关方面,包括创建、启动线程、控制线程,以及多线程的同步操作,并会介绍如何利用Java内建支持的线程池来提高多线程性能。

weixin_43806049的博客 510
上一篇: java 线程池
下一篇: springsecurity3.0.5 filterSecurityInterceptor 使用和配置
rabbit0708
博客等级 码龄15年 12粉丝 27原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值