问题描述
有界缓冲
一个生产者一次放入缓冲区一个产品,且无限次循环
一个消费者一次拿出缓冲区一个产品,且无限次循环
两个进程独立
问题条件;
缓冲池满,则生产者不能放
缓冲池空,则消费者不能取
只能一个生产者/消费者对缓冲区进行操作
分析
(1)进程个数:生产者P1 消费者P2
(2)关系分析:互斥:P1 P2互斥访问 同步:P1生产之后P2才能消费
(3)整理思路:PV解决同步、异步
(4)信号量设置:
①互斥信号量(mutex):初值为1,控制进程互斥访问缓冲池
②同步信号量(full):初值为0,记录缓冲池中“满”的缓冲区的数量
③同步信号量(empty):初值为n,记录缓冲池中“空”的缓冲区的数量
注意项
进程进入临界区前要先检查,若无其他进程访问,则进入临界区并设置访问标志
互斥信号量的PV操作要紧邻临界区。
JAVA实现
要求
生产者和消费者是否想要进入缓冲区是随机的。
代码
package os.First;
import java.util.Random;
/*-----------------------消费者生产者随机访问-----------------------------------*/
public class No1 {
public static void main(String[] args){
while(true) {
Random random=new Random();
int flag=random.nextInt(2);
if(flag==1) {
Producer p=new Producer();
Thread p1=new Thread(p);
p1.start();
}
else {
Consumer q=new Consumer();
Thread q1=new Thread(q);
q1.start();
}
}
}
}
//--------------------PV操作-------------------------
class PV{
int number=0;//初始化信号量
PV(){}
PV(int number){//设置信号量个数
this.number=number;
}
public synchronized void P() {//P操作
number--;
if(number<0) {
try {
this.wait();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void V(){//V操作
number++;
if(number<=0) {
this.notify();
}
}
}
//--------------------------一些初始化---------------------------
class Data{
static PV empty=new PV(10);
static PV full=new PV(0);
static PV mutex=new PV(1);
public static int count=0;
}
//-------------------------生产者------------------------------
/*生产一个产品
P(empty)
P(mutex)
产品放入缓冲区
V(mutex)
V(full) //增加一个产品 */
class Producer implements Runnable{
public void run() {
Data.empty.P();
Data.mutex.P();
System.out.println("生产者生产了产品,该产品被放入了缓冲区,缓冲区产品数量为"+(++Data.count));
Data.mutex.V();
Data.full.V();
}
}
//------------------------------消费者------------------------
/*
P(full)
P(mutex)
从缓冲区取出一个产品
V(mutex)
V(empty)
使用产品
*/
class Consumer implements Runnable{
public void run() {
Data.full.P();
Data.mutex.P();
System.out.println("消费者获得了一个产品,缓冲区产品数量为"+(--Data.count));
Data.mutex.V();
Data.empty.V();
}
}