生产者消费者模式

  • Post author:
  • Post category:其他


一、简述:

生产者消费者模式一般指的是 :

生产者线程负责生产数据存入到一个数据结构中(如果没有空间存储数据就阻塞<消费者有数据能消费就会运行消费方法,因为只有没有数据消费者才阻塞>),

消费者线程负责从此结构中获取生产的数据(如果没有数据就阻塞<生产者有空间存储数据就会运行生产方法, 因为生产者没空间存储才阻塞>)


基本逻辑:生产者线程创建数据,消费者线程删除数据(需要等生产者线程生产数据完毕进入阻塞,消费者才消费)

二、代码示例:

2.1.仓库类:

/**
 * @author zhaoYQ
 */
class Repository_cangKu{
	   private int MAX=20;
	   private List<String> list=new ArrayList<String>();
	   
	   /**入库方法*/
	   public  void addToRepository()throws InterruptedException{//设置锁
		   synchronized(list) {
		       if(list.size()>=MAX){
		    	   System.out.println("仓库已满,请等待有空间了再入库");
		           this.wait();//超过容量时,等待
		       }
		       System.out.println("***开始生产,现在数量为"+list.size()); 
		       list.add("商品");
		       System.out.println("***生产后数量为"+list.size());          
		       this.notify();//唤醒其他线程
		   }
	  }

	  /**出库方法*/
	  public void getFromRepository()throws InterruptedException{
		  synchronized(list) {
	        if(list.size()<0){
	        	System.out.println("库存不足,请稍后再来");
	           this.wait(); //线程休眠
	        }
	              
	        System.out.println("开始消费,现在数量为:"+list.size());
	        list.remove(0);
	        System.out.println("消费后数量为:"+list.size());
	        this.notify();  //唤醒其他线程
		  }
	  }
}

2.2.生产者类:

/**生产者类*/
class Producer extends Thread{  //继承run方法
	   private Repository_cangKu repository;
	   public Producer(Repository_cangKu repository){
	       this.repository=repository;
	   }
	   public void run(){
	       while(true) {
		
				try {
					Thread.sleep(new Random().nextInt(500));  //设置时间延迟
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			
				try {
					repository.getFromRepository();  //调用仓库的出库方法
				} catch (InterruptedException e) {             
					e.printStackTrace();
				}
	        }
	   }
}

2.3.消费者类:

/**消费者线程*/
class Consumer extends Thread{  //继承run方法
	   private Repository_cangKu repository;
	   public Consumer(Repository_cangKu repository){
	       this.repository=repository;
	   }
	   public void run(){
	       while(true) {
		
				try {
					Thread.sleep(new Random().nextInt(500));  //设置时间延迟
				} catch (InterruptedException e) {				
					e.printStackTrace();
				}
			
				try {
					repository.addToRepository();   //调用仓库的入库方法
				} catch (InterruptedException e) {	
					e.printStackTrace();
				}
		  }
	  }
}

2.4.测试类:

package demo1;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class qqq{
	   public static void main(String[]args){
		   Repository_cangKu repository=new Repository_cangKu();//1.创建仓库
		   
		   Producer p1=new Producer(repository);//2.创建 "生产者" 线程
		   Consumer c1=new Consumer(repository); //3.创建 "消费者" 线程
			
		   //4.启动线程
		   p1.start(); //启动生产者线程              
		   c1.start(); //启动消费者线程
			
	  }
}


zhaoYQ 2023-3-1



版权声明:本文为gulanga5原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。