• Java中的生产者、消费者问题


    Java中的生产者、消费者问题描述:

      生产者-消费者(producer-consumer)问题, 也称作有界缓冲区(bounded-buffer)问题, 两个进程共享一个公共的固定大小的缓冲区(仓库). 其中一个是生产者, 用于将产品放入仓库: 另外一个是消费者, 用于从仓库中取出产品消费. 问题出现在当仓库已经满了, 而此时生产者还想向其中放入一个新的产品的情形, 其解决方法是让生产者此时进行等待, 等待消费者从仓库中取走了一个或者多个产品后再去唤醒它. 同样地, 当仓库已经空了, 而消费者还想去仓库消费产品, 此时也可以让消费者进行等待, 等待生产者放入一个或者多个产品时再唤醒它.

    生产者、消费者问题需明确以下信息:

      1、生产者仅仅在仓储未满时候生产, 仓满则停止生产.

      2、生产者在生产出可消费产品时候, 应该通知等待的消费者去消费.

      3、消费者仅仅在仓储有产品时候才能消费, 仓空则等待.

      4、消费者发现仓储没产品可消费时候会通知生产者生产.

    Demo:

    public class ProducerConsumer {
    	public static void main(String[] args){
    		SynStack ss = new SynStack();
    		Producer p = new Producer(ss);
    		Consumer c = new Consumer(ss);
    		Thread p1 = new Thread(p);
    		Thread c1 = new Thread(c);
    		p1.start();
    		c1.start();
    	}
    }
    class Bread {
    	int id;
    	public Bread(int id) {
    		this.id = id;
    	}
    	@Override
    	public String toString() {
    		return "Bread: "+ id;
    	}
    }
    class SynStack {
    	Bread bread[] = new Bread[6];
    	int index = 0;
    	public synchronized void pushBread(Bread bre){
    		while(index == bread.length){
    			try {
    				this.wait();
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    		this.notify();
    		bread[index] = bre;
    		index++;
    	}
    	public synchronized Bread popBread() {
    		while(index == 0){
    			try {
    				this.wait();
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    		this.notify();
    		index--;
    		return bread[index];
    	}
    }
    class Producer implements Runnable{
    	SynStack ss = null;
    	Producer(SynStack ss){
    		this.ss = ss;
    	}
    	@Override
    	public void run() {
    		for(int i=0;i<20;i++){
    			Bread bread = new Bread(i);
    			ss.pushBread(bread);
    			System.out.println("后厨生产了:"+bread);
    		}
    	}
    }
    class Consumer implements Runnable{
    	SynStack ss = null;
    	Consumer(SynStack ss){
    		this.ss = ss;
    	}
    	@Override
    	public void run() {
    		for(int i=0;i<20;i++){
    			Bread bread = ss.popBread();
    			System.out.println("顾客消费了:"+bread);
    			try {
    				Thread.sleep((int)(Math.random()*100));
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    

     某次运行结果:

    后厨生产了:Bread: 0
    后厨生产了:Bread: 1
    后厨生产了:Bread: 2
    顾客消费了:Bread: 0
    后厨生产了:Bread: 3
    后厨生产了:Bread: 4
    后厨生产了:Bread: 5
    后厨生产了:Bread: 6
    顾客消费了:Bread: 6
    后厨生产了:Bread: 7
    顾客消费了:Bread: 7
    后厨生产了:Bread: 8
    后厨生产了:Bread: 9
    顾客消费了:Bread: 8
    顾客消费了:Bread: 9
    后厨生产了:Bread: 10
    顾客消费了:Bread: 10
    后厨生产了:Bread: 11
    顾客消费了:Bread: 11
    后厨生产了:Bread: 12
    顾客消费了:Bread: 12
    后厨生产了:Bread: 13
    顾客消费了:Bread: 13
    后厨生产了:Bread: 14
    顾客消费了:Bread: 14
    后厨生产了:Bread: 15
    顾客消费了:Bread: 15
    后厨生产了:Bread: 16
    顾客消费了:Bread: 16
    后厨生产了:Bread: 17
    顾客消费了:Bread: 17
    后厨生产了:Bread: 18
    顾客消费了:Bread: 18
    后厨生产了:Bread: 19
    顾客消费了:Bread: 19
    顾客消费了:Bread: 5
    顾客消费了:Bread: 4
    顾客消费了:Bread: 3
    顾客消费了:Bread: 2
    顾客消费了:Bread: 1

  • 相关阅读:
    47. Permutations II
    56. Merge Intervals
    57. Insert Interval
    常见算法问题
    67. Unique Paths
    版权声明
    121. Best Time to Buy and Sell Stock
    Leetcode backtracking 合集
    转载 int和string 类型的互换
    prim算法,克鲁斯卡尔算法---最小生成树
  • 原文地址:https://www.cnblogs.com/bosongokay/p/6869795.html
Copyright © 2020-2023  润新知