java 与操作系统进程同步问题(二)————经典消费者生产者问题
http://www.cnblogs.com/zyp4614/p/6033757.html
今天写的是最经典的生产者消费者问题,最简单的版本,即只有一个缓冲区,缓冲区中只能放一个物品,即不考虑互斥关系。
问题简单分析: 生产者在缓冲区为空的时候可以往缓冲区中放产品,消费者可以在缓冲区不空(即缓冲区中有产品时)可以取一个产品。
首先可以确定有两个信号量
第一个信号量,是缓冲区是否空,当空的时候生产者可以放入产品,初值为1,因为默认缓冲区是空的
第二个信号量,是缓冲区是否满,当满的时候消费者可以取出产品,初值为0,因为开始缓冲区内没有产品
/** * 代表缓冲区是否空 */ Semaphore empty; /** * 代表缓冲区是否满 */ Semaphore full;
生产者伪代码如下
wait(empty) //放入产品 signal(full)
消费者伪代码如下:
wait(full) //取产品 signal(empty)
类实现如下
public class ProductAndVistor { Thread producer = new Thread(new Runnable() { @Override public void run() { String className = "producer"; // TODO Auto-generated method stub while(true) { Semaphore.Wait(empty, className); System.out.println(className + "往缓冲区放了一个产品"); //随机生成休眠时间,代表放入产品的操作时间 long millis = (long) (Math.random() * 1000); try { Thread.sleep(millis); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Semaphore.Signal(full, className); } } }); Thread vistor = new Thread(new Runnable() { String className = "vistor"; @Override public void run() { // TODO Auto-generated method stub while(true) { Semaphore.Wait(full, className); System.out.println(className + "从缓冲区取了一个产品"); long millis = (long) (Math.random() * 1000); try { Thread.sleep(millis); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } Semaphore.Signal(empty, className); } } }); /** * 代表缓冲区是否满 */ Semaphore empty; /** * 代表缓冲区是否空 */ Semaphore full; public ProductAndVistor(Semaphore s1, Semaphore s2) { this.empty = s1; this.full = s2; } public ProductAndVistor() { empty = new Semaphore(1); full = new Semaphore(0); } public void start() { producer.start(); vistor.start(); } }