生产者和消费者问题(java简单实现)
来源:互联网 发布:seo软文免费发布渠道 编辑:程序博客网 时间:2024/06/07 19:09
生产者消费者问题(百度百科):生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例。该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。
简单来说:按照通俗理解,我们可以想象,有一个商店仓库,可以存放的商品数量有限,制作商品的厂家(生产者)不停的将生产的商品运送到商店仓库,当商店仓库满了,厂家停止运送商品,进入停工状态。购买者(消费者)可以不停的购买商品仓库的商品,如果仓库没有商品可购买,购买者停止商品。厂家处于停工状态时需得到消费者购买掉商品的信息后,则可继续运送。购买者在无商品可买的状态下需要得到厂家已运送商品的信息后,可继续购买。
怎么知道仓库当前商品的数量呢?是否空或者是否满呢?很容易,数一下当前仓库的商品数量就行了,如果数量为0,那么仓库无货,消费者无法购买,如果数量达到仓库的容量最大值,那么仓库已满,生产者无法继续运送商品进入仓库。
由于厂家和购买者的动作时同时进行,这里容易出现问题,如果在同一时刻有一个商品进又有一个商品出,显然时无法判断仓库商品数量的,这是一个临界问题,宏观上理解就是,如果在一个教室两条门, 在有人同时进门和出门时,你无法判断教室里人的个数一样。在进教室和出教室必须有一个先后关系,也就是在同一时刻,只能有一个人进了教室,或者一个人出了教室。
所以,在java实现生产者和消费者问题时,自然而然用到了synchronized这个关键字,利用它控制生产者和消费者线程在并行状态下,在同一时刻,只能有一个线程操作仓库资源。
知道原理之后,代码就容易写了!
生产者线程代码:
import java.util.*;public class Producer extends Thread{ //list仓库资源,消费者和生产者线程共享 private List<Integer> list; private int max;//仓库能容纳资源最大数量 public Producer(String name,int max,List<Integer> list){ super(name); this.max=max; this.list=list; } public void run(){ while(true){ //加锁,限制在同一时刻只能有同一个线程操作仓库的资源 synchronized(list){ //如果仓库资源满了,生产者无法继续生产资源,则让生产者线程等待 while(list.size()==max){ System.out.println("仓库满了!"); try { list.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //随机生成一个1-100的数字添加进仓库资源 int num=(int)(Math.random()*100)+1; list.add(num); System.out.println(this.getName()+"生产了"+num); list.notify();//唤醒等待的消费者进程 } } }}
消费者线程代码:
import java.util.List;public class Consumer extends Thread{ //list表示仓库资源 private List<Integer> list; private int max;//设置仓库最大容量 //消费者构造函数 public Consumer(String name,int max,List<Integer> list){ super(name); this.max=max; this.list=list; } public void run(){ while(true){ //list是公用资源 synchronized(list){ //如果仓库资源为空,消费者无法获取资源,则让消费者线程等待 while(list.isEmpty()){ System.out.println("仓库空了"); try { list.wait();//线程等待 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //否则执行消费动作 System.out.println(this.getName()+"正在消费"+list.get(list.size()-1)); list.remove(list.size()-1);//消费掉list仓库的尾部一个资源 list.notify();//唤醒其他所有线程 } } }}
测试代码:
import java.util.ArrayList;import java.util.List;public class Test { public static void main(String[] args){ List<Integer> list =new ArrayList<Integer>(); int max=10; Producer p=new Producer("生产者",max,list); Consumer c=new Consumer("消费者",max,list); p.start();//开启生产者线程 c.start();//开启消费者线程 }}
代码中设计的wait()和notify()方法说明:
不是thread方法,而是Object方法
wait():当前线程获取对象的锁后,才调用该对象的wait方法的。调用后,该对象的等待队列中就有了一个所在线程,那个线程进入等待状态,此时,只有该对象调用notify方法,才可以把那个线程从队列里面拿出来,使这个线程成为可运行线程。
notify():唤醒线程等待队列中的线程。由于这个程序中只有生产者和消费者两个线程,所以使用notify唤醒线程没问题。
如果线程等待队列中有多个线程,则采用notifyAll()方法唤醒所有等待线程。
- 生产者和消费者问题(java简单实现)
- 用java实现生产者和消费者问题
- Java实现生产者和消费者问题
- 用java实现生产者和消费者问题
- 生产者和消费者问题的Java实现
- 简单实现生产者消费者问题
- 生产者消费者问题(java实现)
- 生产者和消费者实现(Java)
- 生产者-消费者问题【Java实现】
- 生产者-消费者问题 java实现
- java生产者消费者问题实现
- Java实现生产者消费者问题
- java实现生产者消费者问题
- 生产者消费者问题 --java实现
- Java实现生产者,消费者问题
- java实现生产者消费者问题
- java实现生产者消费者问题
- java实现生产者消费者问题
- mysql学习笔记
- Objective-C 编程基本概念
- 使用GCD进行倒计时操作
- php 远程上传文件 远程上传图片
- 谷歌深度学习公开课学习笔记(0)
- 生产者和消费者问题(java简单实现)
- POJ 3368 ST处理RMQ
- 学习dubbo第一步,了解spring框架的XML扩展特性:让spring加载和解析你自定义的XML文件
- 手机报表参数和结果在一个页面展示
- 异常处理
- Kubenertes资源分配之Request和Limit解析
- javascript作用域
- stm32芯片smartcard功能开发(接触式IC卡)
- Node Server零基础——开发环境文件自动重载