操作系统实验报告-生产者与消费者
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
八、实验总结
这次生产者与消费者之间的关系的实验是用Java语言编写的,用 关键字synchronized来实现多个线程同步,用继承Thread来将生产 者线程与消费者线程实例化。做这个实验能使用到语言编程老师讲过这
些知识,正好可以巩固Java的一些知识。 总之,通过该实验我更加清楚的认识到生产者与消费者这个经典问 题实际上是线程同步问题的抽象描述,即计算机系统中的每个进程都可 以消费(使用)或生产(释放)数据,进程释放数据相当于生产者,使 用数据相当于消费者。
中南大学 操作系统实验报告
实验内容:Java多线程模拟生产者消费者 问题 实验时间:2014年5月 指导老师:胡小龙老师 姓 名:代 巍 班 级:信安1201班 学 号:0909121615
一、实验目的
对操作系统的整体进行一个模拟,通过实践加深对各个部分的管理 功能的认识,还能进一步分析各个部分之间的联系,最后达到对完整系 统的理解。可以提高运用操作系统知识解决实际问题的能力;锻炼实际 的编程能力,要达到以下要求。 (1) 掌握进程(线程)的同步与互斥。 (2) 掌握生产者消费者问题的实现方法。 (3) 掌握多线程编程方法。
} } } } class Producer implements Runnable {//生产者 Storage s = null;
public Producer(Storage s){ this.s = s; } public void run() { for(int i=0; i<20; i++){ Product p = new Product(i); s.push(p); // p); try { Thread.sleep((int) (Math.random()*1500)); } catch (InterruptedException e) { e.printStackTrace(); } } } //放入产品 System.out.println("生产者放入:" +
二、实验内容
实现生产者消费者问题。 (1)假设循环缓冲队列共有多个缓冲单元。 (2)生产者线程的工作:生产出一个产品(即产生一个产品编 号),按顺序往缓冲队列中“空”的缓冲单元放产品。 (3)消费者线程与的工作:从缓冲队列装有产品的缓冲单元中取 出一个产品(即产品编号)。 (4)保证两个线程间的互斥和同步 (5)在界面上打印缓冲队列的变化情况
六、运行结果
七、源程序代码
import javax.swing.*; import java.net.*; import java.io.*; import java.util.*; //java多线程模拟生产者消费者问题 //ProducerConsumer是主类,Producer生产者,Consumer 消费者,Product产品 //Storage仓库
this.products[index] = p; System.out.println("生产者放入"+index+"位 置:" + p); index++; this.notifyAll(); } public synchronized Product pop(){//取出 while(this.index==0){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } index--; this.notifyAll(); System.out.println("消费者从"+ index+ "位 置取出:" + this.products[index]); return this.products[index]; } }
} class Product { int id;
wenku.baidu.com
public Product(int id){ this.id = id; } public String toString(){//重写toString方法 return "产品:"+this.id; } } class Storage { int index = 0; Product[] products = new Product[5]; public synchronized void push(Product p){//放 入 while(index==this.products.length){ try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } }
public class ProducerConsumer { public static void main(String[] args) { Storage s = new Storage(); Producer p = new Producer(s); Consumer c = new Consumer(s); Thread tp = new Thread(p); Thread tc = new Thread(c); tp.start(); tc.start(); } } class Consumer implements Runnable {//消费者 Storage s = null; public Consumer(Storage s){ this.s = s; } public void run() { for(int i=0; i<20; i++){ Product p = s.pop();//取出产品 try { Thread.sleep((int) (Math.random()*1500)); } catch (InterruptedException e) { e.printStackTrace();
五、数据结构说明
(1)Producer类:声明并创建了Producer类, 定义了生产者 的操作。 类Producer 是生产者模型, 其中的run( )方法中定义了生产 者线程所做的操作, 循 环地将生产的“产品”放入缓冲区中, 每次生产完后, 调用 sleep( )方法睡眠一段随机时间, 以给其他线程执行的机会。
(2)Consumer类:声明并创建了Consumer类,定义了消费者的 操作。 类Consumer是消费者模型, 循环地消费“产品”, 从缓冲区中取出 数据, 每次执行完消费操作后, 调用sleep( )方法睡眠一段随机时 间, 以给其他线程执行的机会。 (3)Storage类:声明并创建了Storage类,定义了缓冲区的操 作。提供基本数据结构。 信号量mutex的P V操作及其阻塞队列。 有界缓冲区内设有20个 存储单元,放入取出的产品设定为1-20个整数。对缓冲区的生产和消 费操作都是互斥访问 (4)启动线程:继承Thread(线程)来实现多个生产者与多个消 费者之间的关系,实现Runnable接口来定义一个线程类。 class Producer extends Thread class Consumer extends Thread (5)线程互斥:synchronized关键字可以将一个方法声明为互 斥的方法,即同一时间内只能有一个线程进入该方法的代码执行。 synchronized关键字修饰方法,实现线程互斥。 (6)同步控制:Object类是所有类的父类,该类中提供了实现线 程同步的方法: 等待 public final void wait() throws InterruptedException
四、实验思想概述
在操作系统中, 线程有时被称为轻量级进程, 是CPU 使用的基本单 位, 它与属于同一进程的其他进程共享其他代码段、数据段和其他操作 系统资源。在Java 中, 线程的建立有两种方法: 继承Thread 类和实现 Runnable 接口。其中, 采用实现Runnable 接口建立线程的好处是允 许同时继承其他类从而实现多继承,并且在Java 中, 可采用 synchronized 或Object 类的方法 wait( ), notify( ), notifyAll( )来实现多线程同步。 生产者线程向缓冲区中写数据, 消费者从缓冲区中读数据, 这 样, 在这个程序中同时运行的多个线程竞争同一个缓冲区资源。类 Producer 是生产者模型, 其中的run( )方法中定义了生产者线程所做 的操作, 循环地将生产的“产品”放入缓冲区中, 每次生产完后, 调用 sleep( )方法睡眠一段随机时间, 以给其他线程执行的机会。类 Consumer是消费者模型, 循环地消费“产品”, 从缓冲区中取出数 据, 每次执行完消费操作后, 调用sleep( )方法睡眠一段随机时间, 以 给其他线程执行的机会。
三、实验原理
(1)生产者—消费者问题是一种同步问题的抽象描述。 (2)计算机系统中的每个进程都可以消费或生产某类资源。当系 统中某一进程使用某一资源时,可以看作是消耗,且该进程称为消费 者。 (3)而当某个进程释放资源时,则它就相当一个生产者。 模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中 介。生产者把数据放入缓冲区,而消费者从缓冲区取出数据。大概的结 构如下图。