生产者消费者问题设计与实现

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

操作系统__________________ 课程设计任务书

系(教研室)

主任意见

年月曰

(签字):

目录

1. 选题背景 (1)

2. 设计思路 (1)

3. 过程讨论 (1)

4. 结果分析 (7)

5. 结论 (8)

参考文献 (9)

致谢............................................... 1..0 ........... 附录............................................... 1..0 ........... 指导教师评语......................... 错误 ! 未定义书签。

成绩评定............................. 错...误 !.未. 定义书签。

1. 选题背景

生产者消费者问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品。解决生产者/消费者问题的方法可分为两类:(1)采用某种机制保护生产者和消费者之间的同步;(2)在生产者和消费者之间建立一个管道。第一种方式有较高的效率,并且易于实现,代码的可控制性较好,属于常用的模式。第二种管道缓冲区不易控制,被传输数据对象不易于封装等,实用性不强。因此本文只介绍同步机制实现的生产者/消费者问题。

同步问题核心在于:如何保证同一资源被多个线程并发访问时的完整性。常用的同步方法是采用信号或加锁机制,保证资源在任意时刻至多被一个线程访问。Java语言在多线程编程上实现了完全对象化,提供了对同步机制的良好支持。在Java中一共有四种方法支持同步,其中前三个是同步方法,一个是管道方法。

2. 设计思路

2.1.生产者一消费者问题是一种同步问题的抽象描述。

2.2 计算机系统中的每个进程都可以消费或生产某类资源。当系统中某一进

程使用某一资源时,可以看作是消耗,且该进程称为消费者。

2.3而当某个进程释放资源时,则它就相当一个生产者

3. 过程论述

首先,生产者和消费者可能同时进入缓冲区,甚至可能同时读/写一个存储

单元,将导致执行结果不确定。这显然是不允许的。所以,必须使生产者和消费者互斥进入缓冲区。即某时刻只允许一个实体(生产者或消费者)访问缓冲区,生产者互斥消费者和其他任何生产者。

其次,生产者不能向满的缓冲区写数据,消费者也不能在空缓冲区中取数据,即生产者与消费者必须同步。当生产者产生出数据,需要将其存入缓冲区之前,首先检查缓冲区中是否有“空”存储单元,若缓冲区存储单元全部用完,则生产者必须阻塞等待,直到消费者取走一个存储单元的数据,唤醒它。若缓冲区内有

“空”存储单元,生产者需要判断此时是否有别的生产者或消费者正在使用缓冲区,若是有,则阻塞等待,否则,获得缓冲区的使用权,将数据存入缓冲区,释放缓冲区的使用权。消费者取数据之前,首先检查缓冲区中是否存在装有数据的存储单元,若缓冲区为“空”,则阻塞等待,否则,判断缓冲区是否正在被使用,若正被使用,若正被使用,则阻塞等待,否则,获得缓冲区的使用权,进入缓冲

区取数据,释放缓冲区的使用权3.1系统流程图

3.1.1生产者流程图:

3.1.2消费者流程图:

3.1.3主程序流程图:

3.1.4 生产者:ProducerThread

// 定义生产者线程

class ProducerThread implements Runnable { int productNo = 0; // 产品编号int id ; // 生产者ID public ProducerThread( int id){ this .id = id ;

}

public void run(){ while ( isRun ){ productNo ++; // 生产产品

buffers .put( productNo , id ); // 将产品放入缓冲队列try {

Thread. sleep (1000); } catch (Exception

e){ e.printStackTrace();

} }

}

}

3.1.5 消费者ConsumerThread

// 定义消费者线程

class ConsumerThread implements Runnable { int id ; // 消费者ID public

ConsumerThread( int id){ this .id = id ;

}

public void run(){ while ( isRun ){ buffers .get( id ); // 从缓

冲队列中取出产品try {

Thread. sleep (1000); } catch (Exception

e){ e.printStackTrace();

}

}

}

}

3.1.6 缓冲区Buffer class Buffer {

JTextArea ta;

static final int productBufferNum = 10; // 缓冲单元数ProductBuffer pBuffer [] = new ProductBuffer[ productBufferNum ]; // 缓冲队列

int in = 0; // 缓冲单元指针,用于放产品get()

int out = 0; // 缓冲单元指针,用于取产品put()

int consumeProductNo; // 记录消费产品的编号

int usedBufferNum = 0; // 记录缓冲队列已使用的缓冲单元个数

public Buffer (JTextArea ta){

this .ta = ta ;

// 初始化

for (int j =0; j

pBuffer [j ] = newProductBuffer();

}

for (int i =0; i

pBuffer [i ]. product = -1;

pBuffer [i ]. hasProduct = false ;

}

}

// 取产品

public synchronized void get( int id ){

// 缓冲队列空则等待

if ( usedBufferNum <= 0){

相关文档
最新文档