生产者与消费者课程设计java实现
Java学习教程031405_综合案例:生产者与消费者
Object类对多线程的支持
No.
方法
1
public final void wait() throws InterruptedException
2
public final void wait(long timeout) throws InterruptedException
3
public final void wait(long timeout, int nanos) throws InterruptedException
第14章:多线程编程
综合案例:生产者与消费者
生产者与消费者
➢ 在多线程操作中有一个经典的案例程序 —— 生产者和消费者 问题,生产者不断生产,消费者不断取走生产者生产的产品
解决数据同步问题
➢ 数据同步的问题只能够通过同步代码块或同步方法完成,在本 程序中,生产者和消费者代表着不同的线程对象,所以此时的 同步操作应该设置在Message类之中,可以将title与content 属性设置定义为单独同步方法。
4
public final void notify()
5
public final void notifyAll()
类型 普通
普通
线程的等待
描述
设置线程等待毫秒数
普通
普通 普通
设置线程等待毫秒数和纳秒数
唤醒第一个等待线程 唤醒全部等待线程
生产者消费者等待操作
Java设计模式—生产者消费者模式(阻塞队列实现)
Java设计模式—⽣产者消费者模式(阻塞队列实现)⽣产者消费者模式是并发、多线程编程中经典的,⽣产者和消费者通过分离的执⾏⼯作解耦,简化了开发模式,⽣产者和消费者可以以不同的速度⽣产和消费数据。
这篇⽂章我们来看看什么是⽣产者消费者模式,这个问题也是多线程⾯试题中经常被提及的。
如何使⽤阻塞队列(Blocking Queue)解决⽣产者消费者模式,以及使⽤⽣产者消费者模式的好处。
真实世界中的⽣产者消费者模式⽣产者和消费者模式在⽣活当中随处可见,它描述的是协调与协作的关系。
⽐如⼀个⼈正在准备⾷物(⽣产者),⽽另⼀个⼈正在吃(消费者),他们使⽤⼀个共⽤的桌⼦⽤于放置盘⼦和取⾛盘⼦,⽣产者准备⾷物,如果桌⼦上已经满了就等待,消费者(那个吃的)等待如果桌⼦空了的话。
这⾥桌⼦就是⼀个共享的对象。
在Java Executor框架⾃⾝实现了⽣产者消费者模式它们分别负责添加和执⾏任务。
⽣产者消费者模式的好处它的确是⼀种实⽤的设计模式,常⽤于编写多线程或并发代码。
下⾯是它的⼀些优点:1. 它简化的开发,你可以独⽴地或并发的编写消费者和⽣产者,它仅仅只需知道共享对象是谁2. ⽣产者不需要知道谁是消费者或者有多少消费者,对消费者来说也是⼀样3. ⽣产者和消费者可以以不同的速度执⾏4. 分离的消费者和⽣产者在功能上能写出更简洁、可读、易维护的代码多线程中的⽣产者消费者问题⽣产者消费者问题是⼀个流⾏的⾯试题,⾯试官会要求你实现⽣产者消费者设计模式,以⾄于能让⽣产者应等待如果队列或篮⼦满了的话,消费者等待如果队列或者篮⼦是空的。
这个问题可以⽤不同的⽅式来现实,经典的⽅法是使⽤wait和notify⽅法在⽣产者和消费者线程中合作,在队列满了或者队列是空的条件下阻塞,Java5的阻塞队列(BlockingQueue)数据结构更简单,因为它隐含的提供了这些控制,现在你不需要使⽤wait和nofity在⽣产者和消费者之间通信了,阻塞队列的put()⽅法将阻塞如果队列满了,队列take()⽅法将阻塞如果队列是空的。
用JAVA模拟生产者与消费者的实例
用JAVA模拟生产者与消费者的实例模拟生产者与消费者的实例,生产者生产一个产品,消费者就消费一个产品,然后生产者再生产,消费者再消费。
要求整套源码,程序能独立运行的。
使用的生产者和消费者模型具有如下特点:(1)本实验的多个缓冲区不是环形循环的,也不要求按顺序访问。
生产者可以把产品放到目前某一个空缓冲区中。
(2)消费者只消费指定生产者的产品。
(3)在测试用例文件中指定了所有的生产和消费的需求,只有当共享缓冲区的数据满足了所有关于它的消费需求后,此共享缓冲区才可以作为空闲空间允许新的生产者使用。
(4)本实验在为生产者分配缓冲区时各生产者间必须互斥,此后各个生产者的具体生产活动可以并发。
而消费者之间只有在对同一产品进行消费时才需要互斥,同时它们在消费过程结束时需要判断该消费对象是否已经消费完毕并清除该产品。
Windows 用来实现同步和互斥的实体。
在Windows 中,常见的同步对象有:信号量(Semaphore)、互斥量(Mutex)、临界段(CriticalSection)和事件(Event)等。
本程序中用到了前三个。
使用这些对象都分为三个步骤,一是创建或者初始化:接着请求该同步对象,随即进入临界区,这一步对应于互斥量的上锁;最后释放该同步对象,这对应于互斥量的解锁。
这些同步对象在一个线程中创建,在其他线程中都可以使用,从而实现同步互斥。
当然,在进程间使用这些同步对象实现同步的方法是类似的。
1.用锁操作原语实现互斥为解决进程互斥进人临界区的问题,可为每类临界区设置一把锁,该锁有打开和关闭两种状态,进程执行临界区程序的操作按下列步骤进行:①关锁。
先检查锁的状态,如为关闭状态,则等待其打开;如已打开了,则将其关闭,继续执行步骤②的操作。
②执行临界区程序。
③开锁。
将锁打开,退出临界区。
2.信号量及WAIT,SIGNAL操作原语信号量的初值可以由系统根据资源情况和使用需要来确定。
在初始条件下信号量的指针项可以置为0,表示队列为空。
java网络编程生产者消费者问题
网络编程实验报告实验题目:生产者/消费者问题*名:**学号:**********班级:信息安全091班完成时间:2011.10.25—2011.11.05 ****: ***一、实验概述1.1 实验目的了解进程的同步、互斥机制,认识理解其过程,并用于解决生产者/消费者问题。
使用java编程实现“生产者——消费者”多线程同步问题。
1.2任务描述有两个生产者,每个生产者每次可以生产1个产品,有一个消费者每次消费2个产品,仓库最多只能存放2个产品,若仓库满,则生产者需等待空位来存放产品,若仓库产品数量不足,则消费者需等待来消费产品。
请用多线程技术实现以上功能,要求生产者存放产品时按先来先服务的队列原则来存放产品。
二、功能及处理逻辑设计2.1具体要求1.三个线程。
t0,t1分别代表生产者A,生产者B。
t2代表消费者consumer2.一个仓库(缓冲区),最大存量为两个产品2.1 功能及模块设计2.2特别功能1. Thread.sleep((int)(Math.random()方法令线程随机发生。
2. 用synchronized来实现同步,当仓库满时,等待消费线程,若发生生产者线程则立即等待,进入沉睡状态,当消费线程发生时,同时逐一激活已沉睡生产进程,实现先来先服务。
3. 用synchronized来实现同步,当仓库未满时,发生消费线程,则等待(睡眠),当发生线程,使仓库数为2,激活消费线程。
4. 定义一个新线程必须重写父类的run方法。
2.3算法搭建三、源代码及方法解释(重点步骤已用红色注释)本次方法中未用到队列,利用的是多次调用线程,逐一实现先来先服务import java.util.*;public class xiancheng{public static void main(String[] args){StoreHouse storeHouse = new StoreHouse();Producer producer1 = new Producer("生产者A", storeHouse);Producer producer2 = new Producer("生产者B", storeHouse);Consumer comsumer = new Consumer("消费者", storeHouse);Thread t0 = new Thread(producer1);Thread t1 = new Thread(producer2);Thread t2 = new Thread(comsumer);t0.start();t1.start();t2.start();}}class Producer extends Thread implements Runnable //定义生产者线程{private String producerName = null;private StoreHouse storeHouse = null;public Producer(String producerName, StoreHouse storeHouse) {this.producerName = producerName;this.storeHouse = storeHouse;} //声明生产者要放产品的仓库public void setProducerName(String producerName){this.producerName = producerName;}public String getProducerName(){return producerName;}public void run()//定义一个新线程必须重写父类的run方法{while (true){storeHouse.store_in(this);try{Thread.sleep((int)(Math.random() * 2500));}//定义线程休眠时间catch (InterruptedException e){return;}//有可能抛出异常,必须对它进行捕捉}}}class Consumer extends Thread implements Runnable{//定义消费者线程public String consumerName = null;public StoreHouse storeHouse = null;public Consumer(String consumerName, StoreHouse storeHouse){this.consumerName = consumerName;this.storeHouse = storeHouse;}public void setConsumerName(String consumerName){this.consumerName = consumerName;}public String getConsumerName(){return consumerName;}public void run(){while (true){storeHouse.store_out(this);try{Thread.sleep((int)(Math.random() * 5000)); } //定义线程休眠时间catch (InterruptedException e){return;}}}}class StoreHouse{int count = 0;//创建仓库,用来放产品public synchronized void store_in(Producer pro){while (count == 2) //仓库容量为2{System.out.println("仓库已满," + pro.getProducerName() + "正等待生产...");try{this.wait();//生产者线程进入沉睡}catch (InterruptedException e){}}count++;//产品数自加1System.out.println(pro.getProducerName() + " 生产了 1个产品,库存为" + count); //激活等待的线程,实现先来先服务notify();}public synchronized void store_out(Consumer con){while (count == 0 || count == 1){try{System.out.println("仓库数量不足,消费者等待消费...");this.wait();}catch (InterruptedException e){}}count = count-2;System.out.println(con.getConsumerName() + " 消费了 2个产品,库存为" + count);notify();}}四、程序截图1.先来先服务效果2.消费者等待情况消费者等待的前提下,当仓库数为时立即激活线程,消费当消费者等待时,若仓库每增加一个商品,总会检验是否为满,为则激活消费3.程序效果图总览:其中体现了线程随机性发生,等等各方面情况五、实验总结本次试验我基本上掌握了java多线程同步的方法,完成老师的任务,但是熟练程度还远远未够,将来我也必须更加努力,力求让自己java 编程能力更强。
操作系统中的经典问题——生产者消费者问题(两种方式实现)
操作系统中的经典问题——⽣产者消费者问题(两种⽅式实现)操作系统中的经典问题——⽣产者消费者问题(两种⽅式实现)1、问题引⼊:什么是⽣产者消费者问题?⽣产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是⼀个多线程同步问题的经典案例。
该问题描述了共享固定⼤⼩缓冲区的两个线程——即所谓的“⽣产者”和“消费者”——在实际运⾏时会发⽣的问题。
⽣产者的主要作⽤是⽣成⼀定量的数据放到缓冲区中,然后重复此过程。
与此同时,消费者也在缓冲区消耗这些数据。
该问题的关键就是要保证⽣产者不会在缓冲区满时加⼊数据,消费者也不会在缓冲区中空时消耗数据。
.要解决该问题,就必须让⽣产者在缓冲区满时休眠(要么⼲脆就放弃数据),等到下次消费者消耗缓冲区中的数据的时候,⽣产者才能被唤醒,开始往缓冲区添加数据。
同样,也可以让消费者在缓冲区空时进⼊休眠,等到⽣产者往缓冲区添加数据之后,再唤醒消费者。
通常采⽤进程间通信的⽅法解决该问题。
如果解决⽅法不够完善,则容易出现死锁的情况。
出现死锁时,两个线程都会陷⼊休眠,等待对⽅唤醒⾃⼰。
该问题也能被推⼴到多个⽣产者和消费者的情形。
2、问题分析该问题需要注意的⼏点:1. 在缓冲区为空时,消费者不能再进⾏消费2. 在缓冲区为满时,⽣产者不能再进⾏⽣产3. 在⼀个线程进⾏⽣产或消费时,其余线程不能再进⾏⽣产或消费等操作,即保持线程间的同步4. 注意条件变量与互斥锁的顺序由于前两点原因,因此需要保持线程间的同步,即⼀个线程消费(或⽣产)完,其他线程才能进⾏竞争CPU,获得消费(或⽣产)的机会。
对于这⼀点,可以使⽤条件变量进⾏线程间的同步:⽣产者线程在product之前,需要wait直⾄获取⾃⼰所需的信号量之后,才会进⾏product的操作;同样,对于消费者线程,在consume之前需要wait直到没有线程在访问共享区(缓冲区),再进⾏consume的操作,之后再解锁并唤醒其他可⽤阻塞线程。
消费者、生产者Java代码示例,wait-notify实现
消费者、⽣产者Java代码⽰例,wait-notify实现箱⼦中的苹果代表资源,现在有消费者从箱⼦中拿⾛苹果,⽣产者往箱⼦中放苹果。
代码如下:资源--箱⼦中的苹果:public class Box {int size;int num;public Box(int size, int num) {this.size = size;this.num = num;}public synchronized void put() {try {Thread.sleep(1500);} catch (InterruptedException e) {e.printStackTrace();}while (num == 10) { //⽤while循环检查更好,在下⾯的wait()结束后还再判断⼀次,防⽌虚假唤醒try {System.out.println("箱⼦满了,⽣产者暂停。
");this.wait(); //等待消费者消费⼀个才能继续⽣产,所以要让出锁} catch (InterruptedException e) {e.printStackTrace();} finally {}}num++;System.out.println("箱⼦有空闲,开始⽣产。
"+num);this.notify(); //唤醒可能因为没苹果⽽等待的消费者}public synchronized void take() {try {Thread.sleep(1500);} catch (InterruptedException e) {e.printStackTrace();}while (num == 0) { //⽤while循环检查更好,在wait()结束后还再判断⼀次,防⽌虚假唤醒try {System.out.println("箱⼦空了,消费者暂停。
");this.wait(); //等待⽣产者⽣产⼀个才能继续消费,所以要让出锁} catch (InterruptedException e) {e.printStackTrace();} finally {}}num--;System.out.println("箱⼦有了,开始消费。
操作系统生产者-消费者问题(PV操作)(Java实现)
操作系统⽣产者-消费者问题(PV操作)(Java实现)⼀、问题描述⼀组⽣产者进程和⼀组消费者进程共享⼀个初始为空、⼤⼩n的缓冲区,只有缓冲区没满时,⽣产者才能把资源放⼊缓冲区,否则必须等待;只有缓冲区不为空时,消费者才能从中取出资源,否则必须等待。
由于缓冲区是临界资源,它只允许⼀个⽣产者放⼊资源,或⼀个消费者从中取出资源。
⼆、问题分析(1)、关系分析。
⽣产者和消费者对缓冲区互斥访问是互斥关系,同时⽣产者和消费者⼜是⼀个相互协作的关系,只有⽣产者⽣产之后,消费者只能才能消费,它们还是同步关系。
(2)、整理思路。
只有⽣产⽣产者和消费者进程,正好是这两个进程存在着互斥关系和同步关系,即需要解决的是互斥和同步 PV 操作的位置。
(3)、信号量设置。
信号量 mutex 作为互斥信号量,⽤于控制互斥访问缓冲池,互斥信号量初值为1;信号量 full ⽤于记录当前缓冲池中的“满”缓冲池,初值为0;信号量 empty ⽤于记录当前缓冲池中“空“缓冲区数,初值为n。
三、代码实现import java.util.Scanner;public class ProCon {public static void main(String[] args){int producer,consumer;Scanner sc=new Scanner(System.in);System.out.print("请输⼊⽣产者数⽬:");producer=sc.nextInt();//输⼊⽣产者数量System.out.print("请输⼊消费者数⽬:");consumer=sc.nextInt();//输⼊消费者数量for(int i=0;i<producer;i++){new Thread(new Producer(),"⽣产者"+ Integer.toString(i)+"号").start();//创建⽣产者线程并开启}for(int j=0;j<consumer;j++){new Thread(new Consumer(),"消费者"+ Integer.toString(j)+"号").start();//创建消费者线程并开启}}}class Global{public static Semaphore empty=new Semaphore(3);//空闲缓冲区初始化为三public static Semaphore full=new Semaphore(0);//满缓冲区初始化为空public static Semaphore mutex=new Semaphore(1);//临界区互斥信号量public static int count=0;//count⽤于缓冲区中的进程进⾏计数//定时等待public static void timingwait(){try{Thread.sleep(2000);//Thread.Sleep()⽅法⽤于将当前线程休眠⼀定时间时间单位是ms,1s=1000ms}catch(InterruptedException e)//当使⽤ng.Thread类的sleep⽅法时,可能会导致线程阻塞,需要抛出InterruptedException(中断异常)异常{e.printStackTrace();}}}//⽣产者class Producer implements Runnable//Runnable接⼝创建新线程{@Overridepublic void run()//Runnable 接⼝可以被任何想要被⼀个线程运⾏的接⼝继承实现;继承 Runnable 接⼝的类必须有⼀个 run() ⽅法{Global.timingwait();Global.timingwait();System.out.println(Thread.currentThread().getName()+" ⽣产出⼀个商品...");//Thread.currentThread().getName()获得当前执⾏的线程Global.empty.P();//获取空缓冲区单元Global.mutex.P();//进⼊临界区Global.timingwait();System.out.println(Thread.currentThread().getName()+" 将产品放⼊缓冲区--缓冲区剩余 "+(++Global.count)+" 个产品");Global.mutex.V();//离开临界区,释放信号量Global.full.V();//满缓冲区数加⼀}}//消费者class Consumer implements Runnable{@Overridepublic void run(){Global.timingwait();Global.full.P();//获取满缓冲区单元Global.mutex.P();//进⼊临界区Global.timingwait();System.out.println(Thread.currentThread().getName()+" 从缓冲区取出⼀个产品--缓冲区剩余 "+(--Global.count)+" 个产品");Global.mutex.V();//离开临界区,释放互斥信号量Global.empty.V();//空缓冲区加⼀System.out.println(Thread.currentThread().getName()+" 消费⼀个商品...");}}//信号量class Semaphore{public int value;public Semaphore(int value){super();this.value=value;}//P操作public synchronized final void P()//使⽤synchronized修饰的⽅法,叫做同步⽅法,保证A线程执⾏该⽅法的时,其他线程只能在⽅法外等着.{//被final修饰的⽅法是⼀个最终⽅法,不能被重写,重写会报错value--;if(value<0){try{this.wait();//当缓冲区已满/空时,⽣产者或消费者线程停⽌⾃⼰的执⾏,释放锁,使⾃⼰处于等待状态,让其它线程执⾏}catch(InterruptedException e)//当使⽤ng.Thread类的 wait⽅法时,可能会导致线程阻塞,需要抛出InterruptedException(中断异常)异常{e.printStackTrace();}}}//V操作public synchronized final void V(){value++;if(value<=0){this.notify();//当⽣产者或消费者向缓冲区放⼊或取出⼀个产品时,向其他等待的线程发出通知,同时释放锁,使⾃⼰处于等待状态,让其它线程执⾏。
生产者和消费者课程设计基于Java可视化界面
《操作系统》课程设计生产者和消费者问题实践系院:计算机科学系学生姓名:***学号:**********专业:计算机科学与技术年级:三年级完成日期:2010年12月指导教师:***public JTextArea jt=new JTextArea();//构造方法并对私有变量赋值public Consumer(Share s){shared=s;}//重写父类方法public void run(){int value=0;//默认十次循环,消费者将从共享资源内取出相应资源for(int i=1;i<11;i++){value=shared.get();jieguo[i]="消费者第"+i+"次消费"+" 消费者获得的生产数据:"+value+"\n";jt.append(jieguo[i]);try{sleep(1000);}catch(InterruptedException e){}}}}5、实验运行图;同步运行结果互斥运行结果6、实验结果分析;只有在生产者生产了产品并将产品存放到缓冲池中消费者才能去消费,当缓冲池为空时消费者不能消费六、结论(应当准确、完整、明确精练;也可以在结论或讨论中提出建议、设想、尚待解决问题等。
)七、参考文献【1】邵丽萍,邵光亚,张后扬编著.Java语言程序设计,清华大学出版社。
2008年8月第3版【2】汤小丹,梁红兵,哲凤屏,汤子瀛编著.计算机操作系统,西安电子科技大学出版社。
2007年5月第3版附:课程设计源代码:import java.awt.*;import java.awt.event.*;import javax.swing.*;//窗口类class window extends JFrame{public JFrame jf;public JPanel jp3;public ScrollPane sp1,sp2,sp3;public Container c;window(){jf=new JFrame();jp3=new JPanel();sp1=new ScrollPane();sp2=new ScrollPane();sp3=new ScrollPane();c=getContentPane();c.setLayout(new GridLayout(2,2,10,10));jf.add(c);c.add(sp1);c.add(sp2);c.add(jp3);c.add(sp3);jf.setSize(400,300);jf.setVisible(true);jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}}//Share 类class Share{private int u,jishu=0;private boolean available=false;public JTextArea jt=new JTextArea("==========生产消费状态==========\n\n"); //同步方法public synchronized int get(){jishu++;while(available==false){try{wait();}catch(InterruptedException e){}jt.append(jishu+" Share中没有资源,消费者等待……\n");}available=false;notifyAll();jt.append(jishu+" 正在唤醒生产者生产……\n");return u;}public synchronized void put(int value){jishu++;while(available==true){try{wait();}catch(InterruptedException e){}jt.append(jishu+" Share中已有资源,生产者等待……\n");}u=value;available=true;notifyAll();jt.append(jishu+" 正在唤醒消费者消费……\n");}//互斥方法public int hget(){jishu++;jt.append(jishu+" 消费者正在消费资源……\n");return u;}public void hput(int value){jishu++;jt.append(jishu+" 生产者正在生产资源……\n");u=value;}}//生产者类class Producer extends Thread{private Share shared;public String jieguo[]=new String[11];public JTextArea jt=new JTextArea("==========生产者进程==========\n\n");public Producer(Share s){shared=s;}public void run(){for(int i=1;i<11;i++){shared.put(i);jieguo[i]=i+" 生产者第"+i+"次生产"+" 生产者的生产数据:"+i+"\n";jt.append(jieguo[i]);try{//sleep((int)(Math.random()*100));sleep(1000);}catch(InterruptedException e){}}}}class hProducer extends Thread{private Share shared;public String jieguo[]=new String[11];public JTextArea jt=new JTextArea("==========生产者线程==========\n\n");public hProducer(Share s){shared=s;}public void run(){for(int i=1;i<11;i++){shared.hput(i);jieguo[i]=i+" 生产者第"+i+"次生产"+" 生产者的生产数据:"+i+"\n";jt.append(jieguo[i]);try{//sleep((int)(Math.random()*100));sleep(1000);}catch(InterruptedException e){}}}}//消费者类class Consumer extends Thread{private Share shared;public String jieguo[]=new String[11];public JTextArea jt=new JTextArea("==========消费者线程==========\n\n");public Consumer(Share s){shared=s;}public void run(){int value=0;for(int i=1;i<11;i++){value=shared.get();jieguo[i]=i+" 消费者第"+i+"次消费"+" 消费者获得的生产数据:"+value+"\n";jt.append(jieguo[i]);try{//sleep((int)(Math.random()*100));sleep(1000);}catch(InterruptedException e){}}}}class hConsumer extends Thread{private Share shared;public String jieguo[]=new String[11];public JTextArea jt=new JTextArea("==========消费者线程==========\n\n");public hConsumer(Share s){shared=s;}public void run(){int value=0;for(int i=1;i<11;i++){value=shared.hget();jieguo[i]=i+" 消费者第"+i+"次消费"+" 消费者获得的生产数据:"+value+"\n";jt.append(jieguo[i]);/*try{//sleep((int)(Math.random()*100));sleep(1000);}catch(InterruptedException e){}*/}}}//程序入口public class PCmx{public static void main(String[] args){window win=new window();BHandler h=new BHandler();BHandler1 h1=new BHandler1();JButton jb=new JButton("开始同步线程读写");JButton jb1=new JButton("开始互斥线程读写");win.jf.setTitle("生产者与消费者同步与互斥演示");jb.addActionListener(h);jb1.addActionListener(h1);win.jp3.add(jb);win.jp3.add(jb1);h.winadd(win.jf,win.sp1,win.sp2,win.sp3,win.jp3,win.jp3);h1.winadd(win.jf,win.sp1,win.sp2,win.sp3,win.jp3,win.jp3);}}//同步按钮事件class BHandler implements ActionListener{private ScrollPane sp1,sp2,sp3;private JPanel jp1,jp2;private JFrame jf;JTextArea jt1=new JTextArea();JTextArea jt2=new JTextArea();public void actionPerformed(ActionEvent e){jf.setTitle("生产者与消费者的同步与互斥- 同步演示");Share s=new Share();Producer p=new Producer(s);Consumer c=new Consumer(s);sp1.add(p.jt);sp2.add(c.jt);sp3.add(s.jt);p.start();c.start();}public void winadd(JFrame jff,ScrollPane s1,ScrollPane s2,ScrollPane s3,JPanel j1,JPanel j2){jf=jff;sp1=s1;sp2=s2;sp3=s3;jp1=j1;jp2=j2;}}//互斥按钮事件class BHandler1 implements ActionListener{private ScrollPane sp1,sp2,sp3;private JPanel jp1,jp2;private JFrame jf;JTextArea jt1=new JTextArea();JTextArea jt2=new JTextArea();public void actionPerformed(ActionEvent e){Share s=new Share();hProducer p=new hProducer(s);hConsumer c=new hConsumer(s);sp1.add(p.jt);sp2.add(c.jt);sp3.add(s.jt);jf.setTitle("生产者与消费者的同步与互斥- 互斥演示");p.start();c.start();}public void winadd(JFrame jff,ScrollPane s1,ScrollPane s2,ScrollPane s3,JPanel j1,JPanel j2){jf=jff;sp1=s1;sp2=s2;sp3=s3;jp1=j1;jp2=j2;}}。
生产者与消费者问题在JAVA中的实现
生产者与消费者问题在JAVA中的实现
白戈力
【期刊名称】《读写算(教育教学研究)》
【年(卷),期】2006(27)2
【摘要】生产者与消费者问题是《操作系统》中经典进程同步问题的典型代表。
本文介绍了基于多缓冲区的生产者与消费者问题在 JAVA中的实现机制,其中主要利用了一个数组来模拟具有n个缓冲区的循环缓冲。
这种用 JAVA实现生产者与消费者问题的演示思想不仅可以帮助学生更好的理解所学内容,而且还可以锻炼学生的动手实践能力,具有很强的参考价值和实践意义。
【总页数】5页(P117-121)
【作者】白戈力
【作者单位】内蒙古农业大学计算机与信息工程学院
【正文语种】中文
【中图分类】TP312
【相关文献】
1.生产者与消费者问题在.NET中的设计与实现 [J], 程涛
2.利用JAVA多线程并发机制解决生产者-消费者问题 [J], 陈益
3.基于JAVA线程机制研究生产者-消费者问题 [J], 孔德凤;应时
4.两种解决生产者--消费者问题的Java实现模型 [J], 范容;胡则辉
5.Java生产者和消费者模型分析 [J], 张章松
因版权原因,仅展示原文概要,查看原文内容请购买。
用Java写一个生产者-消费者队列
⽤Java写⼀个⽣产者-消费者队列⽣产者消费者的模型作⽤1. 通过平衡⽣产者的⽣产能⼒和消费者的消费能⼒来提升整个系统的运⾏效率,这是⽣产者消费者模型最重要的作⽤。
2. 解耦,这是⽣产者消费者模型附带的作⽤,解耦意味着⽣产者和消费者之间的联系少,联系越少越可以独⾃发展使⽤阻塞队列来实现package yunche.test.producer;import java.util.Random;import java.util.concurrent.BlockingQueue;/*** @ClassName: Producer* @Description: ⽣产者* @author: yunche* @date: 2018/08/26*/public class Producer implements Runnable{private final BlockingQueue<Integer> queue;public Producer(BlockingQueue q){this.queue = q;}@Overridepublic void run(){try{while(true){//模拟耗时1sThread.sleep(1000);queue.put(produce());}}catch (InterruptedException e){e.printStackTrace();}}private int produce(){int n = new Random().nextInt(10000);System.out.println("Thread: " + Thread.currentThread().getName() + " produce: " + n);return n;}}package yunche.test.producer;import java.util.concurrent.BlockingQueue;/*** @ClassName: Consumer* @Description: 消费者* @author: yunche* @date: 2018/08/26*/public class Consumer implements Runnable{private final BlockingQueue<Integer> queue;public Consumer(BlockingQueue q){this.queue = q;}@Overridepublic void run(){while (true){try{//模拟耗时Thread.sleep(2000);consume(queue.take());}catch (InterruptedException e){e.printStackTrace();}}}private void consume(Integer n){System.out.println("Thread:" + Thread.currentThread().getName() + " consume: " + n); }}package yunche.test.producer;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.BlockingQueue;/*** @ClassName: Main* @Description: 测试类* @author: yunche* @date: 2018/08/26*/public class Main{public static void main(String[] args){BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(100);Producer p = new Producer(queue);Consumer c1 = new Consumer(queue);Consumer c2 = new Consumer(queue);Thread producer = new Thread(p);producer.setName("⽣产者线程");Thread consumer1 = new Thread(c1);consumer1.setName("消费者1");Thread consumer2 = new Thread(c2);consumer2.setName("消费者2");producer.start();consumer1.start();consumer2.start();}}使⽤wait-notify来实现package yunche.test.producer;import java.util.LinkedList;import java.util.Random;/*** @ClassName: Producer* @Description: ⽣产者* @author: yunche* @date: 2018/08/26*/public class Producer implements Runnable{private final LinkedList<Integer> list;/*** 缓冲区⼤⼩*/private final int maxSize;public Producer(LinkedList list, int size){this.list = list;maxSize =size;}@Overridepublic void run(){try{while(true){//模拟耗时1sThread.sleep(1000);synchronized (list){if(list.size()==maxSize){System.out.println("缓冲区已满,正在等待消费者消费..." + System.currentTimeMillis()); list.wait();}else{list.add(produce());list.notifyAll();}}}}catch (InterruptedException e){e.printStackTrace();}}private int produce(){int n = new Random().nextInt(10000);System.out.println("Thread: " + Thread.currentThread().getName() + " produce: " + n);return n;}}package yunche.test.producer;import java.util.Date;import java.util.LinkedList;/*** @ClassName: Consumer* @Description: 消费者* @author: yunche* @date: 2018/08/26*/public class Consumer implements Runnable{private final LinkedList<Integer> list;public Consumer(LinkedList list){this.list = list;}@Overridepublic void run(){while (true){try{synchronized(list){//模拟耗时Thread.sleep(1000);if(list.isEmpty()){System.out.println("缓冲区已空,正在等待⽣产者⽣产..." + System.currentTimeMillis() + Thread.currentThread().getName()); list.wait();}else{consume(list.poll());list.notifyAll();}}}catch (InterruptedException e){e.printStackTrace();}}}private void consume(Integer n){System.out.println("Thread:" + Thread.currentThread().getName() + " consume: " + n);}}package yunche.test.producer;import java.util.ArrayList;import java.util.LinkedList;import java.util.List;/*** @ClassName: Main* @Description: 测试类* @author: yunche* @date: 2018/08/26*/public class Main{public static void main(String[] args){LinkedList<Integer> list = new LinkedList<>();Producer p = new Producer(list, 10);Consumer c1 = new Consumer(list);Consumer c2 = new Consumer(list);Thread producer = new Thread(p);producer.setName("⽣产者线程");Thread consumer1 = new Thread(c1);consumer1.setName("消费者1");Thread consumer2 = new Thread(c2);consumer2.setName("消费者2");producer.start();consumer1.start();consumer2.start();}}参考资料 。
生产者消费者模型-Java代码实现
⽣产者消费者模型-Java代码实现什么是⽣产者-消费者模式 ⽐如有两个进程A和B,它们共享⼀个固定⼤⼩的缓冲区,A进程产⽣数据放⼊缓冲区,B进程从缓冲区中取出数据进⾏计算,那么这⾥其实就是⼀个⽣产者和消费者的模式,A相当于⽣产者,B相当于消费者,⽣产者消费者要解决的问题就是如何处理公共资源。
⽣产者-消费者模式的特点保证⽣产者不会在缓冲区满的时候继续向缓冲区放⼊数据,⽽消费者也不会在缓冲区空的时候,消耗数据当缓冲区满的时候,⽣产者会进⼊休眠状态,当下次消费者开始消耗缓冲区的数据时,⽣产者才会被唤醒,开始往缓冲区中添加数据;当缓冲区空的时候,消费者也会进⼊休眠状态,直到⽣产者往缓冲区中添加数据时才会被唤醒代码实现package com.rao.operatingSystempublic class ProducerAndConsumer {public static void main(String[] args) {Factory factory = new Factory(10);Producer producer = new Producer(factory);Producer producer2 = new Producer(factory);Consumer consumer = new Consumer(factory);producer.start();producer2.start();consumer.start();}/*** ⼯⼚模型,表⽰公共资源*/static class Factory{int max;//⼯⼚的最⼤物品数int num;//当前⼯⼚当中还有多少物品public Factory(int max) {this.max = max;}/*** ⽣产*/synchronized void add(){//如果⼯⼚没有满,就⽣产物品if (num < max){num++;System.out.println("⽣产了⼀件商品,现在⼯⼚中还有:" + num + "件物品");//唤醒等待的消费者来消费notifyAll();}else {try {//⼯⼚满了,⽣产者等待System.out.println("⼯⼚满了,⽣产者等待");wait();} catch (InterruptedException e) {e.printStackTrace();}}}synchronized void remove(){//如果⼯⼚有物品if (0 < num){num--;System.out.println("消费了⼀件物品,还剩下:" + num + "件物品");//唤醒等待的⽣产者来⽣产物品notifyAll();}else {try {//没有东西可以被消费了,该线程等待,等到⽣产者来⽣产System.out.println("⼯⼚没东西了,消费者等待");wait();} catch (InterruptedException e) {e.printStackTrace();}}}}/*** ⽣产者*/static class Producer extends Thread{ Factory factory;public Producer(Factory factory) {this.factory = factory;}@Overridepublic void run() {while (true){//⼀直⽣产try{sleep(1000);} catch (InterruptedException e) { e.printStackTrace();}factory.add();}}}/*** 消费者*/static class Consumer extends Thread{ Factory factory;public Consumer(Factory factory) {this.factory = factory;}@Overridepublic void run() {while (true){//⼀直消费try {sleep(1000);} catch (InterruptedException e) { e.printStackTrace();}factory.remove();}}}}。
Java多线程之并发协作生产者消费者设计模式
Java多线程之并发协作⽣产者消费者设计模式⼀、两个线程⼀个⽣产者⼀个消费者需求情景两个线程,⼀个负责⽣产,⼀个负责消费,⽣产者⽣产⼀个,消费者消费⼀个。
涉及问题同步问题:如何保证同⼀资源被多个线程并发访问时的完整性。
常⽤的同步⽅法是采⽤标记或加锁机制。
wait() / nofity() ⽅法是基类Object的两个⽅法,也就意味着所有Java类都会拥有这两个⽅法,这样,我们就可以为任何对象实现同步机制。
wait()⽅法:当缓冲区已满/空时,⽣产者/消费者线程停⽌⾃⼰的执⾏,放弃锁,使⾃⼰处于等待状态,让其他线程执⾏。
notify()⽅法:当⽣产者/消费者向缓冲区放⼊/取出⼀个产品时,向其他等待的线程发出可执⾏的通知,同时放弃锁,使⾃⼰处于等待状态。
代码实现(共三个类和⼀个main⽅法的测试类)Resource.javapackage com.demo.ProducerConsumer;/*** 资源* @author lixiaoxi**/public class Resource {/*资源序号*/private int number = 0;/*资源标记*/private boolean flag = false;/*** ⽣产资源*/public synchronized void create() {if (flag) {//先判断标记是否已经⽣产了,如果已经⽣产,等待消费;try {wait();//让⽣产线程等待} catch (InterruptedException e) {e.printStackTrace();}}number++;//⽣产⼀个System.out.println(Thread.currentThread().getName() + "⽣产者------------" + number);flag = true;//将资源标记为已经⽣产notify();//唤醒在等待操作资源的线程(队列)}/*** 消费资源*/public synchronized void destroy() {if (!flag) {try {wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(Thread.currentThread().getName() + "消费者****" + number);flag = false;notify();}}Producer.javapackage com.demo.ProducerConsumer;/*** ⽣产者* @author lixiaoxi**/public class Producer implements Runnable{private Resource resource;public Producer(Resource resource) {this.resource = resource;}@Overridepublic void run() {while (true) {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}resource.create();}}}Consumer.javapackage com.demo.ProducerConsumer;/*** 消费者* @author lixiaoxi**/public class Consumer implements Runnable{private Resource resource;public Consumer(Resource resource) {this.resource = resource;}@Overridepublic void run() {while (true) {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}resource.destroy();}}}ProducerConsumerTest.javapackage com.demo.ProducerConsumer;public class ProducerConsumerTest {public static void main(String args[]) {Resource resource = new Resource();new Thread(new Producer(resource)).start();//⽣产者线程new Thread(new Consumer(resource)).start();//消费者线程 }}打印结果:以上打印结果可以看出没有任何问题。
操作系统实验(生产者消费者问题java实现)
操作系统实验(生产者消费者问题java实现)一实验目的1 深刻理解进程同步的概念。
2 掌握经典同步问题,生产者——消费者问题。
二实验设备PC机三实验内容在Java开发平台模拟经典进程同步问题,生产者——消费者问题。
四程序的主要代码import java.awt.*;import javax.swing.*;import java.awt.event.*;public class PAC extends JFrame{protected JButton producer1,producer2,producer3,consumer1,consumer2,consumer3; protected JTextField blank1,blank2,blank3,blank4,blank5;int[] array = new int[5];public PAC(){JPanel p1 = new JPanel(new FlowLayout(FlowLayout.CENTER,2,2));p1.add(producer1 = new JButton("生产者1"));p1.add(producer2 = new JButton("生产者2"));p1.add(producer3 = new JButton("生产者3"));JPanel p2 = new JPanel(new FlowLayout(FlowLayout.CENTER,2,2));p2.add(new JLabel("缓冲区"));p2.add(blank1 = new JTextField(5));p2.add(blank2 = new JTextField(5));JPanel p3 = new JPanel(new FlowLayout(FlowLayout.CENTER,2,2));p3.add(consumer1 = new JButton("消费者1"));p3.add(consumer2 = new JButton("消费者2"));p3.add(consumer3 = new JButton("消费者3"));JPanel p4 = new JPanel(new GridLayout(4,1,2,2));p4.add(new JLabel("阻塞队列"));p4.add(blank3 = new JTextField(5));p4.add(blank4 = new JTextField(5));p4.add(blank5 = new JTextField(5));JPanel p5 = new JPanel(new GridLayout(3,1,10,50));p5.add(p1);p5.add(p2);p5.add(p3);JPanel p6 = new JPanel(new BorderLayout(3,3));p6.add(p4,BorderLayout.EAST);p6.add(p5,BorderLayout.CENTER);setLayout(new FlowLayout(FlowLayout.CENTER,10,20)); this.getContentPane().add(p6);producer1.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){wh(1);}});producer2.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){wh(2);}});producer3.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){wh(3);}});consumer1.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){whh(1);}});consumer2.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){whh(2);}});consumer3.addActionListener(new ActionListener(){public void actionPerformed(ActionEvent e){whh(3);}});}public void wh(int n){for(int i = 0;i < 5; i++){if(array[i] == 0 && array[2] < 0){switch(-array[2]){case 1:consumer1.setEnabled(true);break;case 2:consumer2.setEnabled(true);break;case 3:consumer3.setEnabled(true);break;}array[2] = array[3];array[3] = array[4];array[4] = 0;break;}else if(array[i] == 0 ){if(array[1] == 0){array[i] = n;break;}if(array[1] != 0){array[i] = n;switch(n){case 1:producer1.setEnabled(false);break;case 2:producer2.setEnabled(false);break;case 3:producer3.setEnabled(false);break;}break;}}}blank1.setText(" " + array[0]);blank2.setText(" " + array[1]);blank3.setText(" " + array[2]);blank4.setText(" " + array[3]);blank5.setText(" " + array[4]);}public void whh(int n){if (array[0] != 0){switch(array[2]){case 1:producer1.setEnabled(true);break;case 2:producer2.setEnabled(true);break;case 3:producer3.setEnabled(true);break;}for (int k = 0; k < 4; k++)array[k] = array[k + 1];array[4] = 0;}else{for (int k = 2; k < 5; k++){if (array[k] == 0){array[k] = -n;switch(n){case 1:consumer1.setEnabled(false);break;case 2:consumer2.setEnabled(false);break;case 3:consumer3.setEnabled(false);break;}break;}}}blank1.setText(" " + array[0]);blank2.setText(" " + array[1]);blank3.setText(" " + array[2]);blank4.setText(" " + array[3]);blank5.setText(" " + array[4]);}public static void main(String[] args){PAC frame = new PAC();frame.pack();frame.setTitle("生产者与消费者问题实验");frame.setSize(500,300);frame.setLocationRelativeTo(null);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}}/**生产者1、2、3分别生产数字1、2、3;消费者1、2、3的消费请求进入阻塞队列后分别对应-1、-2、-3。
java生产者与消费者模式
java⽣产者与消费者模式前⾔:⽣产者和消费者模式是我们在学习多线程中很经典的⼀个模式,它主要分为⽣产者和消费者,分别是两个线程,⽬录⼀:⽣产者和消费者模式简介⼆:⽣产者和消费者模式的实现声明:本例来源于java经典著作:《Think in java》,接下来将会采⽤本例⼦将会借鉴其中的案例进⾏分析⾸先我们来设想有⼀个这样的场景:⼀个饭店⾥有⼀个做饭的厨师和来吃饭的⼈,服务员负责端⾷物,这⾥就可以把厨师当做⽣产者,(这⾥暂且把服务员当做消费者),⽽⾷物则有这样的过程,被厨师⽣产出来,然后被服务员消费。
当⾷物存在的时候,厨师等待,不再进⾏⽣产,服务员进⾏消费。
当⾷物为空的时候,厨师开始⽣产⾷物,服务员等待。
这中间就存在着⼀个线程之间协作的过程。
我们来通过代码进⾏模拟:⾸先是新建两个线程,⼀个厨师线程,⼀个服务员线程,双⽅进⾏协作:以下是厨师线程:public class Chef implements Runnable{ //productprivate Restaurant restaurant;private int count=0;public Chef(Restaurant restaurant) {this.restaurant = restaurant;}@Overridepublic void run() {try {while (!Thread.interrupted()) {synchronized (this) {while (restaurant.meal != null) {wait();}if (++count==10){System.out.println("out of food,closing");restaurant.exec.shutdownNow();}System.out.println("Chef product meal"+count);synchronized (restaurant.waitPerson){restaurant.meal= new Meal(count);restaurant.waitPerson.notifyAll();}TimeUnit.MICROSECONDS.sleep(100);}}}catch (InterruptedException e){System.out.println("Chef interruped");}}}以下是服务员线程:public class WaitPerson implements Runnable{private Restaurant restaurant;public WaitPerson(Restaurant restaurant) {this.restaurant = restaurant;}@Overridepublic void run() {try{while (!Thread.interrupted()) {synchronized (this) {while (restaurant.meal == null) {wait();}System.out.println("waitPerson got:"+restaurant.meal);}synchronized (restaurant.chef){restaurant.meal=null;restaurant.chef.notifyAll();}}} catch (InterruptedException e) {e.printStackTrace();System.out.println("waitPerson interrupdate");}}}我们来分析⼀下厨师线程,主要看它的run⽅法,⾥⾯包含着⼀个try、catch块,⾸先它会⼀直捕获线程的状态,当它不处于interrupted(线程中断,此时⽆法运转)异常时,往下⾛。
计算机操作系统课程设计报告《生产者---消费者问题》
《计算机操作系统》课程设计题目:生产者---消费者问题专业:软件工程年级:2010级小组成员: A B指导教师:时间:地点:2012年5 月摘要生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例。
该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。
生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。
与此同时,消费者也在缓冲区消耗这些数据。
该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。
生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
目录1. 概述 (4)2. 课程设计任务及要求 (4)2.1 设计任务 (4)2.2 设计要求 (4)2.3 分工日程表 (4)3. 算法及数据结构 (5)3.1算法的总体思想 (5)3.2 生产者模块 (5)3.3 消费者模块 (7)4. 程序设计与实现 (8)4.1 程序流程图 (8)4.2 程序代码 (9)4.3 实验结果 (14)5. 结论 (17)6. 收获、体会和建议 (17)6.1收获......................................... 错误!未定义书签。
7. 参考文献 (18)1. 概述本课题设计是完成了“操作系统原理”课程进行的一次全面的综合训练,通过这次课程设计,充分检验学生对课程的掌握程度和熟练情况,让学生更好的掌握操作系统的原理及其实现方法,加深对课程的基础理论和算法的理解,加强学生的动手能力。
Java实现Kafka生产者和消费者的示例
Java实现Kafka⽣产者和消费者的⽰例Kafka简介Kafka是由Apache软件基⾦会开发的⼀个开源流处理平台,由Scala和Java编写。
Kafka的⽬标是为处理实时数据提供⼀个统⼀、⾼吞吐、低延迟的平台。
⽅式⼀:kafka-clients引⼊依赖在pom.xml⽂件中,引⼊kafka-clients依赖:<dependency><groupId>org.apache.kafka</groupId><artifactId>kafka-clients</artifactId><version>2.3.1</version></dependency>⽣产者创建⼀个KafkaProducer的⽣产者实例:@Configurationpublic class Config {public final static String bootstrapServers = "127.0.0.1:9092";@Bean(destroyMethod = "close")public KafkaProducer<String, String> kafkaProducer() {Properties props = new Properties();//设置Kafka服务器地址props.put("bootstrap.servers", bootstrapServers);//设置数据key的序列化处理类props.put("key.serializer", StringSerializer.class.getName());//设置数据value的序列化处理类props.put("value.serializer", StringSerializer.class.getName());KafkaProducer<String, String> producer = new KafkaProducer<>(props);return producer;}}在Controller中进⾏使⽤:@RestController@Slf4jpublic class Controller {@Autowiredprivate KafkaProducer<String, String> kafkaProducer;@RequestMapping("/kafkaClientsSend")public String send() {String uuid = UUID.randomUUID().toString();RecordMetadata recordMetadata = null;try {//将消息发送到Kafka服务器的名称为“one-more-topic”的Topic中recordMetadata = kafkaProducer.send(new ProducerRecord<>("one-more-topic", uuid)).get();("recordMetadata: {}", recordMetadata);("uuid: {}", uuid);} catch (Exception e) {log.error("send fail, uuid: {}", uuid, e);}return uuid;}}消费者创建⼀个KafkaConsumer的消费者实例:@Configurationpublic class Config {public final static String groupId = "kafka-clients-group";public final static String bootstrapServers = "127.0.0.1:9092";@Bean(destroyMethod = "close")public KafkaConsumer<String, String> kafkaConsumer() {Properties props = new Properties();//设置Kafka服务器地址props.put("bootstrap.servers", bootstrapServers);//设置消费组props.put("group.id", groupId);//设置数据key的反序列化处理类props.put("key.deserializer", StringDeserializer.class.getName());//设置数据value的反序列化处理类props.put("value.deserializer", StringDeserializer.class.getName());props.put("mit", "true");props.put("mit.interval.ms", "1000");props.put("session.timeout.ms", "30000");KafkaConsumer<String, String> kafkaConsumer = new KafkaConsumer<>(props);//订阅名称为“one-more-topic”的Topic的消息kafkaConsumer.subscribe(Arrays.asList("one-more-topic"));return kafkaConsumer;}}在Controller中进⾏使⽤:@RestController@Slf4jpublic class Controller {@Autowiredprivate KafkaConsumer<String, String> kafkaConsumer;@RequestMapping("/receive")public List<String> receive() {从Kafka服务器中的名称为“one-more-topic”的Topic中消费消息ConsumerRecords<String, String> records = kafkaConsumer.poll(Duration.ofSeconds(1));List<String> messages = new ArrayList<>(records.count());for (ConsumerRecord<String, String> record : records.records("one-more-topic")) {String message = record.value();("message: {}", message);messages.add(message);}return messages;}}⽅式⼆:spring-kafka使⽤kafka-clients需要我们⾃⼰创建⽣产者或者消费者的bean,如果我们的项⽬基于SpringBoot构建,那么使⽤spring-kafka 就⽅便多了。
生产者消费者问题Java三种实现
⽣产者消费者问题Java三种实现⽣产者-消费者Java实现2017-07-271 概述⽣产者消费者问题是多线程的⼀个经典问题,它描述是有⼀块缓冲区作为仓库,⽣产者可以将产品放⼊仓库,消费者则可以从仓库中取⾛产品。
解决⽣产者/消费者问题的⽅法可分为两类:采⽤某种机制保护⽣产者和消费者之间的同步;在⽣产者和消费者之间建⽴⼀个管道。
第⼀种⽅式有较⾼的效率,并且易于实现,代码的可控制性较好,属于常⽤的模式。
第⼆种管道缓冲区不易控制,被传输数据对象不易于封装等,实⽤性不强。
在Java中有四种⽅法⽀持同步,其中前三个是同步⽅法,⼀个是管道⽅法。
wait() / notify()⽅法await() / signal()⽅法BlockingQueue阻塞队列⽅法PipedInputStream / PipedOutputStream本⽂只介绍前三种。
2 实现2.1 wait() / notify()⽅法wait() / nofity()⽅法是基类Object的两个⽅法:wait()⽅法:当缓冲区已满/空时,⽣产者/消费者线程停⽌⾃⼰的执⾏,放弃锁,使⾃⼰处于等等状态,让其他线程执⾏。
notify()⽅法:当⽣产者/消费者向缓冲区放⼊/取出⼀个产品时,向其他等待的线程发出可执⾏的通知,同时放弃锁,使⾃⼰处于等待状态。
缓冲区Storage.java代码如下:import java.util.LinkedList;public class Storage{// 仓库最⼤存储量private final int MAX_SIZE = 100;// 仓库存储的载体private LinkedList<Object> list = new LinkedList<Object>();// ⽣产产品public void produce(String producer){synchronized (list){// 如果仓库已满while (list.size() == MAX_SIZE){System.out.println("仓库已满,【"+producer+"】:暂时不能执⾏⽣产任务!");try{// 由于条件不满⾜,⽣产阻塞list.wait();}catch (InterruptedException e){e.printStackTrace();}}// ⽣产产品list.add(new Object());System.out.println("【"+producer+"】:⽣产了⼀个产品\t【现仓储量为】:" + list.size()); list.notifyAll();}}// 消费产品public void consume(String consumer){synchronized (list){//如果仓库存储量不⾜while (list.size()==0){System.out.println("仓库已空,【"+consumer+"】:暂时不能执⾏消费任务!");try{// 由于条件不满⾜,消费阻塞list.wait();}catch (InterruptedException e){e.printStackTrace();}}list.remove();System.out.println("【"+consumer+"】:消费了⼀个产品\t【现仓储量为】:" + list.size()); list.notifyAll();}}public LinkedList<Object> getList(){return list;}public void setList(LinkedList<Object> list){this.list = list;}public int getMAX_SIZE(){return MAX_SIZE;}}View CodeTest.javapublic class Test {public static void main(String[] args){Storage storage=new Storage();for(int i=1;i<6;i++){int finalI = i;new Thread(new Runnable() {@Overridepublic void run() {storage.produce(String.format("⽣成者%d:", finalI));}}).start();}for(int i=1;i<4;i++){int finalI = i;new Thread(()-> storage.consume(String.format("消费者%d:", finalI))).start();}}}View Code结果如下:仓库已空,【消费者1】:暂时不能执⾏消费任务!【⽣产者3】:⽣产了⼀个产品【现仓储量为】:1【消费者2】:消费了⼀个产品【现仓储量为】:0仓库已空,【消费者3】:暂时不能执⾏消费任务!【⽣产者1】:⽣产了⼀个产品【现仓储量为】:1【⽣产者4】:⽣产了⼀个产品【现仓储量为】:2【⽣产者2】:⽣产了⼀个产品【现仓储量为】:3【⽣产者5】:⽣产了⼀个产品【现仓储量为】:4【消费者1】:消费了⼀个产品【现仓储量为】:3【消费者3】:消费了⼀个产品【现仓储量为】:22.2 await() / signal()⽅法await()和signal()的功能基本上和wait() / nofity()相同,完全可以取代它们,但是它们和新引⼊的锁定机制Lock直接挂钩,具有更⼤的灵活性。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
public String jieguo[]=new String[11];
public JTextArea jt=new JTextArea("==========生产者线程==========\n\n");
public hProducer(Share s){
public Container c;
window(){
jf=new JFrame();
jp3=new JPanel();
sp1=new ScrollPane();
sp2=new ScrollPane();
sp3=new ScrollPane();
c=getContentPane();
try{
//sleep((int)(Math.random()*100));
sleep(1000);
}catch(InterruptedException e){}
}
}
}
class hProducer extends Thread{
shared=s;
}
public void run(){
int value=0;
for(int i=1;i<11;i++){
value=shared.hget();
jieguo[i]=i+" 消费者第"+i+"次消费"+" 消费者获得的生产数据:"+value+"\n";
JTextArea jt2=new JTextArea();
public void actionPerformed(ActionEvent e){
jf.setTitle("生产者与消费者的同步与互斥- 同步演示");
Share s=new Share();
Producer p=new Producer(s);
//同步方法
public synchronized int get(){
jishu++;
while(available==false){
try{wait();}
catch(InterruptedException e){}
jt.append(jishu+" Share中没有资源,消费者等待……\n");
}
public void run(){
for(int i=1;i<11;i++){
shared.put(i);
jieguo[i]=i+" 生产者第"+i+"次生产"+" 生产者的生产数据:"+i+"\n";
jt.append(jieguo[i]);
}
available=false;
notifyAll();
jt.append(jishu+" 正在唤醒生产者生产……\n");
return u;
}
public synchronized void put(int value){
jishu++;
notifyAll();
jt.append(jishu+" 正在唤醒消费者消费……\n");
}
//互斥方法
public int hget(){
jishu++;
jt.append(jishu+" 消费者 正在消费资源……\n");
return u;
while(available==true){
try{wait();}
catch(InterruptedException e){}
jt.append(jishu+" Share中已有资源,生产者等待……\n");
}
u=value;
available=true;
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
//Share 类
class Share{
private int u,jishu=0;
private boolean available=false;
public JTextArea jt=new JTextArea("==========生产消费状态==========\n\n");
private Share shared;
public String jieguo[]=new String[11];
public JTextArea jt=new JTextArea("==========消费者线程==========\n\n");
public hConsumer(Share s){
shared=s;
}
public void run(){
int value=0;
for(int i=1;i<11;i++){
value=shared.get();
jieguo[i]=i+" 消费者第"+i+"次消费"+" 消费者获得的生产数据:"+value+"\n";
p.start();
c.start();
try{
//sleep((int)(Math.random()*100));
sleep(1000);
}catch(InterruptedException e){}
}
}
}
//消费者类
class Consumer extends Thread{
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
//窗口类
class window extends JFrame{
public JFrame jf;
public JPanel jp3;
public ScrollPane sp1,sp2,sp3;
c.setLayout(new GridLayout(2,2,10,10));
jf.add(c);
c.add(sp1);
c.add(sp2);
c.add(jp3);
c.add(sp3);
jf.setSize(400,300);
jf.setVisible(true);
win.jp3.add(jb);
win.jp3.add(jb1);
h.winadd(win.jf,win.sp1,win.sp2,win.sp3,win.jp3,win.jp3);
h1.winadd(win.jf,win.sp1,win.sp2,win.sp3,win.jp3,win.jp3);
JButton jb=new JButton("开始同步线程读写");
JButton jb1=new JButton("开始互斥线程读写");
win.jf.setTitle("生产者与消费者同步与互斥演示");
jb.addActionListener(h);
jb1.addActionListener(h1);
public class PCmx{
public static void main(String[] args){
window win=new window();
BHandler h=new BHandler();
BHandler1 h1=new BHandler1();
Share s=new Share();
hProducer p=new hProducer(s);
hConsumer c=new hConsumer(s);
sp1.add(p.jt);
sp2.add(c.jt);
sp3.add(s.jt);
jf.setTitle("生产者与消费者的同步与互斥- 互斥演示");
public String jieguo[]=new String[11];
public JTextArea jt=new JTextArea("==========生产者进程==========\n\n");
public Producer(Share s){
shared=s;
shared=s;
}
public void run(){
for(int i=1;i<11;i++){
shared.hput(i);
jieguo[i]=i+" 生产者第"+i+"次生产"+" 生产者的生产数据:"+i+"\n";
jt.append(jieguo[i]);
}
public void hput(int value){
jishu++;
jt.append(jishu+" 生产者 正在生产资源……\n");