【多线程】生产者和消费者模型(一)
分析:
生产者和消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内公用同一个仓库,生产者向仓库中存放数据,消费者从仓库中取出数据。
生产者/消费者模型的问题关键在于如何保证生产者不会在仓库满时再加入数据,消费者也不会在仓库空时再消耗数据。为了解决这个问题,我们只需要在生产和消费时增加条件,数据大于仓库容量时生产者停止工作,等消费者消耗数据后才能被唤醒,开始向仓库添加数据;数据小于0时消费者停止工作,等生产者生产数据后才能被唤醒,开始消耗仓库中的数据。
设计与实现:
仓库Store类,size表示仓库容量,count表示仓库当前数据量,生产者线程调用addData()方法生产数据,消费者线程调用removeData()方法消耗数据。
生产和消耗数据时,检查仓库中的数据量能否进行相应操作,不能则调用wait()方法使线程等待。
public class Store { private int size=100; private int count; public synchronized void addData(){ if(count==size){ try { this.wait(); }catch (InterruptedException e){ e.printStackTrace(); } } count++; System.out.println(Thread.currentThread().getName()+"add Data:"+count); this.notifyAll(); } public synchronized void removeData(){ if(count==0){ try { this.wait(); }catch (InterruptedException e){ e.printStackTrace(); } } count--; System.out.println(Thread.currentThread().getName()+"remove Data:"+count); this.notifyAll(); } }
生产者线程使用Store中的addData()方法添加数据。
public class Producer implements Runnable{ private Store store; public Producer(Store store) { this.store = store; } @Override public void run() { try { for(int i=0;i<50;i++){ store.addData(); Thread.sleep(100); } }catch (InterruptedException e){ e.printStackTrace(); } } }
消费者线程使用Store中的removeDate()方法消耗数据。
public class Customer implements Runnable{ private Store store; public Customer(Store store) { this.store = store; } @Override public void run() { try { for(int i=0;i<100;i++){ store.removeData(); Thread.sleep(100); } }catch (InterruptedException e){ e.printStackTrace(); } } }
测试类Test。
public class Test { public static void main(String[] args) { Store s=new Store(); Runnable producer=new Producer(s); Runnable customer=new Customer(s); Thread p1=new Thread(producer,"生产者1"); Thread p2=new Thread(producer,"生产者2"); Thread c1=new Thread(customer,"消费者"); p1.start(); p2.start(); c1.start(); } }

生产者/消费者模型的synchronized实现方法
浙公网安备 33010602011771号