使用管程法
属性定义
缓冲区的容量为10生产者将生产100个面包消费者将消费105个面包
思路
生产者不停地生产,生产结果放进缓冲区
消费者不停地消费,从缓冲区中取走产品
当缓冲区为10时,停止生产,线程阻塞
当缓冲区为0时,停止消费,线程阻塞
当成功生产一个后,唤醒所有线程
当成功消费一个后,唤醒所有线程
以下两种方式运行结果相同:
方法一:同步块
package cn.hanquan.test;/** 生产者消费者问题——管程法* 缓冲区的容量为10* 生产者将生产100个面包* 消费者将消费100个面包*/public class ProducerConsumer {public static void main(String[] args) {Stack s = new Stack();Consumer c = new Consumer(s);Producer p = new Producer(s);c.start();p.start();}}//面包class Bread {int num;public Bread(int num) {this.num = num;}public Bread() {}}//缓冲区class Stack {Bread[] breads = new Bread[10];int total = 0;public void push(Bread b) {if(total==breads.length) {try {this.wait();//线程阻塞} catch (InterruptedException e) {}}breads[total] = b;try {Thread.sleep(20);//模拟延时} catch (InterruptedException e) {}total++;this.notifyAll();}public Bread pop() {if(total==0) {try {this.wait();//线程阻塞} catch (InterruptedException e) {}}total--;try {Thread.sleep(90);//模拟延时} catch (InterruptedException e) {}this.notifyAll();Bread b = new Bread();b = breads[total];return b;}}//生产者class Producer extends Thread {Stack s;public Producer(Stack s) {this.s = s;}public void run() {for (int i = 0; i < 105; i++) {synchronized(s) {s.push(new Bread(i));}System.out.println("生产" + i);}}}//消费者class Consumer extends Thread {Stack s;public Consumer(Stack s) {this.s = s;}public void run() {for (int i = 0; i < 100; i++) {synchronized(s) {System.out.println("消费" + s.pop().num);}}}}
方法二:同步方法
package cn.hanquan.test;/** 生产者消费者问题——管程法* 缓冲区的容量为10* 生产者将生产100个面包* 消费者将消费100个面包*/public class ProducerConsumer {public static void main(String[] args) {Stack s = new Stack();Consumer c = new Consumer(s);Producer p = new Producer(s);c.start();p.start();}}//面包class Bread {int num;public Bread(int num) {this.num = num;}public Bread() {}}//缓冲区class Stack {Bread[] breads = new Bread[10];int total = 0;public synchronized void push(Bread b) {if (total == breads.length) {try {this.wait();// 线程阻塞} catch (InterruptedException e) {}}breads[total] = b;try {Thread.sleep(20);// 模拟延时} catch (InterruptedException e) {}total++;this.notifyAll();}public synchronized Bread pop() {if (total == 0) {try {this.wait();// 线程阻塞} catch (InterruptedException e) {}}total--;try {Thread.sleep(90);// 模拟延时} catch (InterruptedException e) {}this.notifyAll();Bread b = new Bread();b = breads[total];return b;}}//生产者class Producer extends Thread {Stack s;public Producer(Stack s) {this.s = s;}public void run() {for (int i = 0; i < 105; i++) {s.push(new Bread(i));System.out.println("生产" + i);}}}//消费者class Consumer extends Thread {Stack s;public Consumer(Stack s) {this.s = s;}public void run() {for (int i = 0; i < 100; i++) {System.out.println("消费" + s.pop().num);}}}
运行结果
生产0消费0生产1消费1生产2消费2生产3消费3生产4消费4生产5消费5生产6消费6生产7消费7生产8消费8生产9消费9生产10消费10生产11消费11生产12消费12生产13消费13生产14消费14生产15消费15生产16消费16生产17消费17生产18消费18生产19消费19生产20消费20生产21消费21生产22消费22生产23消费23生产24消费24生产25消费25生产26消费26生产27消费27生产28消费28生产29消费29生产30消费30生产31消费31生产32消费32生产33消费33生产34消费34生产35消费35生产36消费36生产37消费37生产38消费38生产39消费39生产40消费40生产41消费41生产42消费42生产43消费43生产44消费44生产45消费45生产46消费46生产47消费47生产48消费48生产49消费49生产50消费50生产51消费51生产52消费52生产53消费53生产54消费54生产55消费55生产56消费56生产57消费57生产58消费58生产59消费59生产60消费60生产61消费61生产62消费62生产63消费63生产64消费64生产65消费65生产66消费66生产67消费67生产68消费68生产69消费69生产70消费70生产71消费71生产72消费72生产73消费73生产74消费74生产75消费75生产76消费76生产77消费77生产78消费78生产79消费79生产80消费80生产81消费81生产82消费82生产83消费83生产84消费84生产85消费85生产86消费86生产87消费87生产88消费88生产89消费89生产90消费90生产91消费91生产92消费92生产93消费93生产94消费94生产95消费95生产96消费96生产97消费97生产98消费98生产99消费99生产100生产101生产102生产103生产104