资讯详情

Java学习进程15

📅 2026/10/9 2:44:02 | 华诺云谱 👁 阅读
Java学习进程15
生产消费模型在 Java 多线程编程中生产者与消费者通常需要通过某个共享资源进行数据交互。生产者负责向共享仓库中添加数据消费者负责从共享仓库中取出数据。当生产速度和消费速度不一致时就需要通过线程同步、等待与唤醒机制来控制线程执行从而保证数据安全并避免线程无意义地占用 CPU。核心通过共享仓库 synchronized wait/notify实现生产者和消费者之间的线程协作。1.基本结构生产消费模型主要包含三个部分生产者负责生成数据并放入仓库线程 │ │ 生产数据 ↓ ┌─────────────────┐ │ 共享仓库 │ 生产者和消费者之间进行数据交换的共享资源 │ │ │ [数据][数据] │ │ [数据] │ └─────────────────┘ ↑ │ 消费数据 │ 消费者负责从仓库中取出数据线程共享仓库是生产者线程和消费者线程之间的数据交换媒介。2.关于共享仓库的有限容量实际情况下共享仓库通常不能无限存放数据。将出现两个问题仓库已满当前数据 仓库容量生产者继续生产将无法继续放入数据若继续添加可能造成数据溢出或逻辑错误。仓库为空仓库容量已满当前数据 0消费者没有数据可以消费也不应该不断循环检查将不断占用 CPU。不能直接停止线程在高并发环境中频繁创建和销毁线程会产生额外的性能开销。解决方法线程暂时进入等待状态。仓库满 ↓ 生产者进入 WAITING ↓ 放弃 CPU ↓ 消费者消费数据 ↓ 仓库出现空位 ↓ 唤醒生产者 ↓ 继续生产wait() 方法等待synchronized(warehouse){//当前线程进入等待状态。warehouse.wait();}之后线程会主动放弃执行 ↓ 进入 WAITING 状态 ↓ 释放当前监视器锁 ↓ 等待其他线程唤醒注:wait() 不会让线程永久停止而是让线程进入等待状态。notify() 方法唤醒当其他线程完成操作后使用synchronized(warehouse){warehouse.notify();}唤醒正在等待的线程执行过程线程A ↓ wait() ↓ WAITING ↓ 线程B修改共享数据 ↓ notify() ↓ 线程A被唤醒 ↓ 重新竞争锁 ↓ 继续执行另外1.wait() 和 notify() 必须使用同一个对象若同步锁对象和等待、唤醒对象不一致会导致程序逻辑错误。2.wait() 、 notify() 和 notifyAll() 属于Object类的方法因为任何对象都可以作为监视器锁对象。3.在写生产消费模型时验证操作最好放在线程安全的状态下执行即添加 synchronized()。示例代码Producer 生产者类packagecom.sy.producer_consumer0923;importjava.util.List;/** * author rephemera * description 生产者 * * wait(): 执行该方法的线程会进入等待状态 * 进入该状态后不能主动恢复到运行状态 * 直到另一个线程利用同一个对象调用 notify() 方法 * 才能唤醒该线程 */publicclassProducerimplementsRunnable{// 仓库publicListIntegerlist;publicintMax20;// 仓库的最大值// 重写 run 方法publicvoidrun(){while(true){// 同步代码块在线程安全的状态执行// 监视器对象必须和调用 wait 方法的对象保持一致synchronized(list){// 判断仓库容量if(list.size()Max){// 生产一个数据list.add(1);// 唤醒消费者list.notify();}else{// 当线程进入等待状态挂起try{list.wait();}catch(InterruptedExceptione){thrownewRuntimeException(e);}System.out.println(仓库已经生产者进入等待状态...);}}}}}Manage 测试类packagecom.sy.producer_consumer0923;/** * author rephemera * description */publicclassManage{publicstaticvoidmain(String[]args){// 仓库对象ProducerproducernewProducer();newThread(producer).start();newThread(producer).start();// 创建消费者对象启动线程}}生产消费模型的应用场景生产消费模型适用于多个线程之间的数据传递、任务分配以及线程之间的协同问题的场景。1.游戏中的敌人生成与销毁射击游戏中可以限制同一画面中的敌人数量,避免同时存在过多敌人减少系统资源占用。敌人数量达到上限 ↓ 生产者暂停生成敌人 ↓ 消费者/游戏逻辑销毁敌人 ↓ 敌人数量下降 ↓ 唤醒生产者 ↓ 继续生成新的敌人2.任务队列一个线程不断产生任务其他线程负责处理任务。如用户请求产生任务、后台线程从任务队列中获取任务、多个消费者线程并行处理任务。生产者 ↓ 任务队列 ↓ 消费者 ↓ 执行任务3.数据处理生产者负责不断读取或生成数据消费者负责对数据进行处理。如文件读取 → 数据处理、网络数据接收 → 数据解析、日志产生 → 日志处理。数据产生 ↓ 共享缓冲区 ↓ 数据处理4.消息队列生产者将消息放入队列消费者从队列中取出消息进行处理。当消息队列达到容量上限时生产者暂时等待当队列出现空闲空间后再继续生产。生产者 ↓ 消息队列 ↓ 消费者5.多线程下载/上传多个线程可以负责产生下载或上传任务其他线程负责执行实际的数据传输。通过生产消费模型可以控制任务数量避免同时创建过多任务造成资源浪费。任务生成线程 ↓ 任务队列 ↓ 下载/上传线程
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑