【OS】 JAVA 管程 单消费者-生产者问题

为什么要引入管程

答:为了解决信号量机制编程麻烦,易出错的问题。

之前我们学习了信号量机制,在使用过程中发现了诸多不便。缺点如下:
1.在使用过程中若是PV顺序不当会出现死锁
2.进程对临界资源访问都有自己的临界区,临界区管理不方便。

管程的组成

管程=共享资源+同步操作
1.共享数据结构
2.对数据结构初始化的语句
3.一组用来访问数据结构的过程(函数)

管程的基本特征

1.封装于管程内部的数据结构仅能被封装于管程内部的过程所访问
2.一个进程只有通过调用管程内的过程才能进入管程访问共享数据
3.管程每次只允许一个进程进入管程执行管程内的过程

进程和管程的区别

1.进程定义的是私有数据结构PCB,管程定义的是公共数据结构
2.进程目的在于实现系统的并发性和占有系统资源;管程的设置是解决共享资源的互斥使用问题。
3.进程是由顺序程序执行有关操作,而管程主要是进行同步操作和初始化操作
4.进程通过调用管程中的过程对共享数据结构实行操作,该剁成就如通常的子程序一样被调用,因而管程是被动工作方式,进程是主动工作方式
5.进程之间能并发执行,而管程不能与其调用者并发
6.进程具有动态性,由“创建”而诞生,由“撤销”而消亡,而管程是操作系统中的一个资源管理模块,供进程调用。

其他补充

各进程必须互斥访问管程的特性是编译器实现的。可在管程中设置条件变量及等待/唤醒操作以解决同步问题。

管程解决单生产者-消费者问题

java实现
对了,我这题要求生产者和消费者随机访问临界区。

package os;

import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class No2 {

	public static void main(String[] args) {
		tube info=new tube();
		while(true) {
			Random random=new Random();
			int flag=random.nextInt(2);
			if(flag==1) {
				Produce p=new Produce(info);
				Thread p1=new Thread(p);
				p1.start();
			}
			else {
				Consume q=new Consume(info);
				Thread q1=new Thread(q);
				q1.start();
			}
		}
	}

}
//管程
//组成:1.共享数据结构2.对数据结构初始化的语句3.一组用来访问数据结构的过程(函数)
class tube{
/*--------------1.共享数据-缓冲池----------------------------------------*/
	private final static int N=10;//设置缓冲池的容量为10
	private int count;
	private Lock lock;
	//条件变量
	private Condition notfull;
	private Condition notempty;
	//容量
/*-----------2.多个过程,用来被外部进程调用从而访问共享数据-----------------*/
	//生产者将自己生产的产品放入缓冲池中,
	//count表示在缓冲池中已有的产品数目,count>=N,生产者等待
	void put() {
		lock.lock();
		while(count>=N) {
			try {
				System.out.println("缓冲池满了,生产者被阻塞!");
				notfull.await();
			}catch(InterruptedException e) {
				e.printStackTrace();
			}
		}
		count++;
		System.out.println("生产者生产了一个产品,缓冲池产品数量为:"+count);
		notempty.signal();
		lock.unlock();
		
	}
	//消费者从缓冲池中取一个产品,当count<=0,消费者应等待
	void get() {
		lock.lock();
		while(count<=0) {
			try {
				System.out.println("缓冲池是空的,消费者被阻塞!");
				notempty.await();
			}catch(InterruptedException e) {
				e.printStackTrace();
			}
		}
		count--;
		System.out.println("消费者消耗了一个产品,缓冲池产品数量为:"+count);
		notfull.signal();
		lock.unlock();
	}
/*--------------3.共享数据的初始化代码--------------------------------------*/
	public tube() {
		this.count=0;
		this.lock=new ReentrantLock();
		this.notfull=lock.newCondition();
		this.notempty=lock.newCondition();
	}
}

//生产者
class Produce implements Runnable{
	private tube info;
	public Produce(tube info) {
		this.info=info;
	}
	public void run() {
		while(true) {
		try {
			info.put();
			Thread.sleep(100);
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
		}
	}
}


//消费者
 class Consume implements Runnable{
	private tube info;
	public Consume(tube info) {
		this.info=info;
	}
	public void run() {
		while(true) {
		try {
			info.get();
			Thread.sleep(100);
		}catch(InterruptedException e) {
			e.printStackTrace();
		}
	}
	}
}

结果显示:
在这里插入图片描述
无数次,后面就不截图了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值