大纲:java线程知识体系

一、概念

生产者消费者问题也称有限缓冲问题(Bounded-buffer problem),是一个多线程同步问题的经典案例。该问题描述了共享固定大小缓冲区的两个线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。 要解决该问题,就必须让生产者在缓冲区满时休眠(要么干脆就放弃数据),等到下次消费者消耗缓冲区中的数据的时候,生产者才能被唤醒,开始往缓冲区添加数据。同样,也可以让消费者在缓冲区空时进入休眠,等到生产者往缓冲区添加数据之后,再唤醒消费者。通常采用进程间通信的方法解决该问题。如果解决方法不够完善,则容易出现死锁的情况。出现死锁时,两个线程都会陷入休眠,等待对方唤醒自己。该问题也能被推广到多个生产者和消费者的情形。

二、问题分析

  • 在缓冲区为空时,消费者不能再进行消费
  • 在缓冲区为满时,生产者不能再进行生产
  • 在一个线程进行生产或消费时,其余线程不能再进行生产或消费等操作,即保持线程间的同步
  • 注意条件变量与互斥锁的顺序


由于前两点原因,因此需要保持线程间的同步,即一个线程消费(或生产)完,其他线程才能进行竞争CPU,获得消费(或生产)的机会。对于这一点,可以使用条件变量进行线程间的同步:生产者线程在product之前,需要wait直至获取自己所需的信号量之后,才会进行product的操作;同样,对于消费者线程,在consume之前需要wait直到没有线程在访问共享区(缓冲区),再进行consume的操作,之后再解锁并唤醒其他可用阻塞线程。
在访问共享区资源时,为避免多个线程同时访问资源造成混乱,需要对共享资源加锁,从而保证某一时刻只有一个线程在访问共享资源。

/*
解题思路
1、分清资源类和线程类 => 资源类是将其封装成Clerk类,由Clerk操作共享资源。线程类分别是消费者线程和生成者线程
2、确定共享资源 => Clerk类或产品数量
3、是否涉及线程通信 => 为了协调生产和消费的步调必须进行线程通信
4、是否涉及线程安全 => 两类线程操作共享资源比如产生线程安全问题(用同步方法,同步代码块,Lock解决)
5、对共享资源的操作也需要在资源类中去完成,然后在线程的run方法中直接调用封装好的操作方法技巧口诀:①判断等待(满足条件则通过wait进入等待)②干活,也就是生产num++ or 消费num--;③唤醒:干活后通过notify唤醒其它线程*/class Clerk{//产品数上限为10public static int MAX_PRODUCT = 10;//当前第几个产品public static int num;public synchronized void product(){String name = Thread.currentThread().getName();if(num <=  MAX_PRODUCT){num++;System.out.println("生产者" +name + " 生产第:" +num +"件商品");notifyAll();}else{System.out.println("生产过多,停止生产");try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}}public synchronized void consumer(){String name = Thread.currentThread().getName();if(num > 0){System.out.println("消费者" +name + " 消费第:" +num +"件商品");num--;notifyAll();}else{try {System.out.println("产品不足,停止消费");this.wait();} catch (InterruptedException e) {e.printStackTrace();}}}
}class Consumer implements Runnable{private Clerk clerk;public Consumer(Clerk clerk) {this.clerk = clerk;}@Overridepublic void run() {while (true){clerk.consumer();}}
}class Productor implements Runnable{private Clerk clerk;public Productor(Clerk clerk) {this.clerk = clerk;}@Overridepublic void run() {String name = Thread.currentThread().getName();while (true){clerk.product();}}
}
/*
1、该模拟中一个生产者对应两个消费者,生产者和消费者必须用同一个clerk来构造否则无法协调工作
2、两个消费者线程必须用同一个customer构造,否则会出现线程安全问题,如果用不同的customer构造
需要将同步方法声明为静态同步方法
3、一个生产者对应多个消费者就会经常出现消费大于生成的场景,反之就会出现生成大于消费的场景,我们还
可以使用sleep来阻碍生产或消费*/
public class Test {public static void main(String[] args) {Clerk clerk = new Clerk();Consumer consumer = new Consumer(clerk);Thread customer = new Thread(new Consumer(clerk));customer.setName("customer");Thread customer2 = new Thread(new Consumer(clerk));customer2.setName("customer2");Thread productor = new Thread(new Productor(clerk));customer.setName("productor");customer.start();
//        customer2.start();productor.start();}
}

结果是随机的,无限循环的。大体如上分析

生产者消费者案例java代码相关推荐

  1. Java实现生产者消费者案例

    目录 一.生产者消费者模式概述 二.生产者消费者案例 三.代码 奶箱类(Box): 生产者类(Producer): 消费者类(Customer): 测试类(BoxDemo): 四.运行结果 一.生产者 ...

  2. 生产者消费者--TestPC.java

    package org.shw.pc; public class TestPC {public static void main(String[] args) { Info info = new In ...

  3. 7.生产者消费者 案例 (使用Lock 同步锁 方式,使用Condition完成线程之间的通信)...

    1 /* 2 * 生产者消费者 案例 (使用Lock 同步锁 方式,使用Condition完成线程之间的通信) 3 * */ 4 public class TestProductorAndConsum ...

  4. 生产者消费者问题Java三种实现

    生产者-消费者Java实现 2017-07-27 1 概述 生产者消费者问题是多线程的一个经典问题,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品. 解决生产者/ ...

  5. 生产者消费者模型java实现

    做题的时候遇到了生产者消费者问题,这个问题可以说是线程学习的经典题目了,就忍不住研究了一波.它描述是有一块缓冲区(队列实现)作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品.在Java ...

  6. 一个简单的生产者消费者案例

    生产者消费者模式 为什么要引入生产者消费者模式 简单来说就是为了解决多线程下程序先后执行问题 遇到的例:实际生产中出现的场景 服务D依赖于服务A.B.C产生的数据,服务D必须等待A.B.C产生结果并持 ...

  7. 线程同步 生产者消费者 java_Java线程同步:生产者-消费者 模型(代码示例)

    public class ThreadSyn { public static void main(String[] args) { new ThreadSyn(); } public ThreadSy ...

  8. 生产者消费者问题(代码实现)

    生产者-消费者问题(也被称为有界缓冲器问题)是一个典型的例子多线程同步的问题.问题描述了两个进程,生产者和消费者,谁都有一个共同的,固定大小的缓冲区作为一个队列.制片人的工作是生成数据,把它放入缓冲区 ...

  9. 基于Lock的卖票和生产者消费者案例

    1.三个售票员卖出30张票 线程 操作(对外暴露的调用方法) 资源类 2.生产者消费者问题 题目:现在两个线程,可以操作初始值为零的一个变量,实现一个线程对该变量加1,一个线程对该变量减1,实现交替, ...

最新文章

  1. React源码分析与实现(一):组件的初始化与渲染
  2. VTK:可视化之MoveActor
  3. 主席树的各类模板(区间第k大数【动,静】,区间不同数的个数,区间=k的个数)...
  4. 现代软件工程讲义 4 团队和流程
  5. Linux修改文件句柄数与vm.max_map_count参数
  6. 打车应用上马快递业务靠谱吗?
  7. 解决红蜘蛛教师端教师图标显示灰色导致无法广播的问题
  8. Python制作翻译软件(中英文互译)
  9. IEC 60068-2 规范介绍
  10. 【Antd】Pagination中的current和pageSize参数自动同步到url当中
  11. 计算机二级正式样式在哪里,满分新建样式,修改样式要学会-计算机二级等考office的省时利器...
  12. 数字化转型的1个目标,3大领域,6大因素和9个环节
  13. 中国象棋-单机游戏-微信小程序的项目开发流程详解
  14. 绘画入门经典教程——如果你想, 一切皆有可能!
  15. 企业级计算机储存容量,家用NAS与企业级NAS功能大比拼
  16. 【小结】南京大学软件工程专硕2021二战小结
  17. H1B工作签证紧俏 “中签率”低对中国留学生影响大-中新网
  18. 2022 年你必须知道的 10 个 Python 库
  19. Linux学习第九节课
  20. 利用wireShark抓取iphone手机上的网络通信包

热门文章

  1. 【javascript动画系列之网页白板】javascript实现的白板(兼容ff,ie,chrome,……)
  2. HTTP--历史、组件系统
  3. 前端基础-git(二):轻松搞定git创建仓库,操作仓库内容
  4. HTML-列表、表格、表单
  5. android mkv 字幕乱码,Android 西班牙语字幕乱码 字符编码
  6. Cycle-1(循环)
  7. myeclipse 添加mysql数据库_myeclipse添加数据库
  8. excel导入mysql命令行_使用命令行将Excel数据表导入Mysql中的方法小结
  9. pta-5、产生每位数字相同的n位数 (10 分)
  10. 顺序表 (数组) 详解