生产者消费者问题java程序设计报告.docx
- 文档编号:1986271
- 上传时间:2023-05-02
- 格式:DOCX
- 页数:22
- 大小:107.03KB
生产者消费者问题java程序设计报告.docx
《生产者消费者问题java程序设计报告.docx》由会员分享,可在线阅读,更多相关《生产者消费者问题java程序设计报告.docx(22页珍藏版)》请在冰点文库上搜索。
生产者消费者问题java程序设计报告
重庆交通大学
《计算机操作系统》课程设计报告
班级:
计软专业2013级2班
姓名:
学号:
课程设计题目:
生产者消费者问题
所属课程:
计算机操作系统
实验室(中心):
语音楼801
指导教师:
完成时间:
2015年11月25日
信息科学与工程学院课程设计成绩单
课程名称:
计算机操作系统指导教师:
刘洋
姓名
刘克
性别
男
学号
631306050224
班级
软件130*
综合成绩
程序运行情况
(占总成绩20%)
□能正确运行□基本能正确运行□能运行但结果不完善
(20分)(15分)(10分)
程序功能完善程度
(占总成绩10%)
□完善□基本完善□不完善
(10分)(8分)(5分)
程序结构的合理性
(占总成绩10%)
□合理□基本合理□不太合理
(10分)(8分)(5分)
对问题的答辩情况
(占总成绩40%)
□概念正确有创新□能正确回答所有问题□基本能正确回答
(40分)(35分)(30分)
□部分问题回答概念不清晰
(20分)
学生的工作态度与独立工作能力
(占总成绩10%)
□工作态度认真能独立完成任务□工作态度认真但独立性较差
(10分)(8分)
□工作态度基本认真但缺乏独立性
(5分)
设计报告的规范性
(占总成绩10%)
□符合规范□基本符合规范□规范性较差
(10分)(8分)(5分)
重庆交通学院信息科学与工程学院课程设计任务书
课程
计算机操作系统
班级
软件2013级2班
指导教师
刘洋
题目
生产者消费者问题
完成时间
2015年6月日
至2015年11月日
主要
内容
利用程序界面模拟生产者消费者进程调度问题
设计报告要求
1.封面;
2.课程设计成绩单、课程设计任务书
3.内容提要;
4.“课程设计报告”正文部分:
主要应包括:
①问题分析和任务定义;
②环境简介;
③设计:
主要是指数据结构与核心算法的设计描述;操作界面的设计;主要功能的算法框架;测试用例设计等内容。
④编译参数与步骤的说明;
⑤上机调试总结与分析;
⑥用户使用说明;
⑦测试数据与测试结果等内容。
⑧课程设计总结:
可以包括课程设计过程的收获、遇到的问题及解决过程的思考、对数据结构这门课程的思考和认识等内容。
⑨附录程序清单
5.参考文献
版面要求
1.题目用黑体三号,段后距18磅(或1行),居中对齐;
2.标题用黑体四号,段前、段后距6磅(或0.3行);
3.正文用小四号宋体,行距为1.25倍行距;
4.标题按“一”、“㈠”、“1”、“⑴”顺序编号。
指导时间安排
星期
周次
一
二
三
四
五
六
17周
18周
指导
地点
一、问题分析和任务定义
(1)问题分析
生产者消费者问题(英语:
Producer-consumerproblem),也称有限缓冲问题(英语:
Bounded-bufferproblem),是一个多线程同步问题的经典案例。
该问题描述了两个共享固定大小缓冲区的线程——即所谓的“生产者”和“消费者”——在实际运行时会发生的问题。
生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。
与此同时,消费者也在缓冲区消耗这些数据。
该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。
(2)任务定义
利用java写可视化程序,绘制三个矩形,分别表示生产进程、缓冲区、消费进程。
定义一个栈作为缓冲区,栈的大小固定。
定义两个线程分别控制生产过程和消费过程。
生产过程:
图片向右移动,移动到一定位置,表明生产完成。
则向栈中压入一个元素。
判断是否可以生产的标准是栈是否已经满,为此要定义一个IsFull函数来判断栈是否已满。
如果已满则不可生产。
消费过程:
从栈中弹出一个元素放在消费进程矩形之中,图片开始向右移动,移动出矩形则停止移动。
二、环境简介
开发工具:
eclipse
操作系统:
win10
三、设计
(1)界面设计
如上图所示界面上有3个矩形,上面那个是生产矩形,中间的是缓冲区矩形,下面的是消费矩形。
四个按钮分别是“开始生产”、“开始消费”、“停止生产”、“停止生产”、“停止消费”。
(2)算法设计
定义一个栈来作为缓冲区,用来存储图片,定义一个生产者线程和一个消费者线程。
两个线程分别控制图片的移动。
生产者线程的图片一旦运动到一定位置,则向栈中压入一个图片元素,与此同时,缓冲区则显示一个产品。
开始消费时,消费者线程则从栈中取出一个图片元素,这时缓冲区则减少一个产品,并且开始在消费矩形中开始运动,运动到一定位置停止。
定义update函数来更新界面显示内容:
publicvoidUpdate()
{
inty[]={20,230,440};
if(pictureProduce!
=null)
{
if(!
Id.isEmpty())
{
Id.lastElement().setBounds(20+(Id.size()-1)*125,230,120,120);
}
pictureProduce.setBounds(x[0],y[0],120,120);//再次设置生产图片位置
}
else{
x[0]=20;
b[0]=false;//为空则不能生产
}
//只要消费者图片不为空就可以显示
if(pictureConsume!
=null)
{
pictureConsume.setBounds(x[1],y[2],120,120);
}
else{
x[1]=20;
b[1]=false;
}
//如果缓冲区满了,则不可生产
if(isfull())
{
b[0]=false;
}
repaint();
}
定义set_x函数来控制图片横坐标位置:
publicbooleanset_x(inti,intn)
{
if(b[i]==true)
{
//设置生产者与消费者的横坐标,不断向前
x[i]=n;
//设置生产者生产完成回到起点
if(n>=599&&i==0)
{
x[0]=20;//生产者回到起点
Id.push(pictureProduce);//添加到栈中添加一个产品,此时缓冲区并没有产品
image=produce();
pictureProduce=newJLabel(image);
add(pictureProduce);
}
elseif(n==20&&i==1||n>=599&&i==1)
{
if(n==20&&i==1)//如果是可以消费
{
if(!
Id.isEmpty())//当缓冲区不为空时,可以消费
pictureConsume=consume();
else
pictureConsume=null;
}
//System.out.println(n);
if(x[1]>=599&&i==1)
{
pictureConsume.setVisible(true);
x[1]=20;
}
}
returntrue;
}
elsereturnfalse;
}
四、上机调试总结与分析;
调试结果显示:
生产者消费者问题的基本功能已经实现,基本没有bug。
五、用户使用说明;
点击“开始生产”则图片开始运动,表示正在生产,图片运动出生产矩形之后,表示生产完成,此时缓冲区则显示一个图片。
点击“停止生产”则生产进程停止。
点击“开始消费”则缓冲区会少一个产品,表示从缓冲区取走了一个产品消费,同时图片开始在消费矩形之中运动,运动出消费矩形之后停止。
点击“停止消费”则消费进程停止。
六、测试数据与测试结果等内容。
测试结果如下:
初始界面
生产出一个产品之后继续生产
一边生产一边消费
七、课程设计总结
从这次的课程设计我还是有很多收获的,首先是对于生产者消费者问题有了更深刻的了解,这个问题是典型的多线程问题,在学习java的时候,老师经常讲这个问题,但那时只是知道大概是什么意思。
通过这次自己动手模拟这个问题,我才知道生产者消费者问题其实主要考虑缓冲区的问题,缓冲区满则不可生产,缓冲区空则不可消费。
其次,我对于java的线程的使用也熟悉了很多,线程是java的重点和难点,但是我们平时并没有对于线程做很多的练习,所以对于线程可谓是一知半解。
通过这次的实验,我使用了多线程的技术,对于的线程的应用方法以及编写方法有了比较深入的了解。
以后再遇见线程问题应该可以游刃有余了。
八、附录程序清单
1.DrawPanel类代码
importjava.awt.Color;
importjava.awt.Font;
importjava.awt.Graphics;
importjava.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
importjava.util.Stack;
importjava.util.function.Consumer;
importjavax.jws.soap.SOAPBinding.Style;
importjavax.swing.Icon;
importjavax.swing.ImageIcon;
importjavax.swing.JButton;
importjavax.swing.JLabel;
importjavax.swing.JPanel;
importjavax.swing.plaf.basic.BasicInternalFrameTitlePane.IconifyAction;
importorg.omg.CORBA.IRObjectOperations;
publicclassDrawPanelextendsJPanelimplementsActionListener//面板类用于绘图及事件处理
{
privateIconimage=null;
privateStack
booleanb[]=newboolean[2];//设置两个状态标识,b[0]为true是可以生产,b[1]为true是可以消费
privateintmax=7;//缓冲区最大值
privatemythreadthreadProduce;//生产者线程
privatemythreadthreadComsume;//消费者线程
privateJButtonbtStartProduce;
privateJButtonbtnStartCosume;
privateJButtonbtnStopConsume;
privateJButtonbtnStopProduce;
privateJLabelpictureProduce;
privateJLabelpictureConsume;
//privateJLabelnameAndId;
intx[]=newint[2];
publicintget_x(inti)//得到生产、消费横坐标
{
returnx[i];
}
publicbooleanset_x(inti,intn)
{
if(b[i]==true)
{
//设置生产者与消费者的横坐标,不断向前
x[i]=n;
//设置生产者生产完成回到起点
if(n>=599&&i==0)
{
x[0]=20;//生产者回到起点
Id.push(pictureProduce);//添加到栈中添加一个产品,此时缓冲区并没有产品
image=produce();
pictureProduce=newJLabel(image);
add(pictureProduce);
}
elseif(n==20&&i==1||n>=599&&i==1)
{
if(n==20&&i==1)//如果是可以消费
{
if(!
Id.isEmpty())//当缓冲区不为空时,可以消费
pictureConsume=consume();
else
pictureConsume=null;
}
//System.out.println(n);
if(x[1]>=599&&i==1)
{
pictureConsume.setVisible(true);
x[1]=20;
}
}
returntrue;
}
elsereturnfalse;
}
publicImageIconproduce()
{
returnnewImageIcon("C:
\\Users\\fff\\Downloads\\9b5edaa1b776898353c47675929cbd5d.jpg");
}
publicJLabelconsume()
{
returnId.pop();
}
publicbooleanisfull()//判断缓冲区是否已经满了
{
if(Id.size()==max)
returntrue;
elsereturnfalse;
}
publicDrawPanel()
{
try{
b[0]=false;//初始状态既不可生产也不可消费
b[1]=false;
x[0]=x[1]=20;//设置三个起始横坐标
inty[]={20,230,440};
setLayout(null);
image=produce();
pictureProduce=newJLabel(image);//为生产者图片赋值
pictureProduce.setBounds(x[0],y[0],120,120);//初始状态下的生产者图片位置
//实例化生产与消费者对象
threadProduce=newmythread(0,this);
threadComsume=newmythread(1,this);
//启动线程
threadProduce.start();
threadComsume.start();
add(pictureProduce);
btStartProduce=newJButton("开始生产");
btStartProduce.addActionListener(this);//添加本类中的的actionPerformed(ActionEventarg0)方法
btnStartCosume=newJButton("开始消费");
btnStartCosume.addActionListener(newActionListener(){
@Override
publicvoidactionPerformed(ActionEventarg0){
//TODOAuto-generatedmethodstub
b[1]=true;
}
});
btnStopConsume=newJButton("停止消费");
btnStopConsume.addActionListener(newActionListener(){
@Override
publicvoidactionPerformed(ActionEvente){
//TODOAuto-generatedmethodstub
b[1]=false;
}
});
btnStopProduce=newJButton("停止生产");
btnStopProduce.addActionListener(newActionListener(){
@Override
publicvoidactionPerformed(ActionEvente){
//TODOAuto-generatedmethodstub
b[0]=false;
}
});
add(btStartProduce);
add(btnStartCosume);
add(btnStopConsume);
add(btnStopProduce);
repaint();
}catch(Exceptione){
//TODO:
handleexception
}
}
publicvoidpaint(Graphicsg)
{
super.paint(g);
inty[]={20,230,440};//三个矩形的纵坐标
btStartProduce.setBounds(100,170,150,30);
btnStartCosume.setBounds(100,600,150,30);
btnStopConsume.setBounds(300,600,150,30);
btnStopProduce.setBounds(300,170,150,30);
g.setColor(Color.gray);
g.drawRect(20,y[0],575,120);//绘制生产矩形
g.drawRect(20,y[1],870,120);//绘制缓冲区矩形
g.drawRect(20,y[2],575,120);//绘制消费矩形
g.setColor(Color.black);
Fontfont=newFont("楷体",Font.BOLD,20);
g.setFont(font);
g.drawString("631306050224刘克软件二班",100,390);
}
//更新界面显示内容
publicvoidUpdate()
{
inty[]={20,230,440};
if(pictureProduce!
=null)
{
if(!
Id.isEmpty())
{
Id.lastElement().setBounds(20+(Id.size()-1)*125,230,120,120);
}
pictureProduce.setBounds(x[0],y[0],120,120);//再次设置生产图片位置
}
else{
x[0]=20;
b[0]=false;//为空则不能生产
}
//只要消费者图片不为空就可以显示
if(pictureConsume!
=null)
{
pictureConsume.setBounds(x[1],y[2],120,120);
}
else{
x[1]=20;
b[1]=false;
}
//如果缓冲区满了,则不可生产
if(isfull())
{
b[0]=false;
}
repaint();
}
@Override
publicvoidactionPerformed(ActionEvente){
//TODOAuto-generatedmethodstub
try{
if(!
threadProduce.isAlive())//唤醒生产线程
threadProduce.notify();
b[0]=true;
}catch(Exceptione2){
//TODO:
handleexception
}
repaint();
}
}
2.mythread类代码
publicclassmythreadextendsThread
{
privateintid;//序号
privateintn;//坐标位置
privateDrawPanelpanel;
publicmythread(inti,DrawPaneld)
{
id=i;
panel=d;
}
publicintget_n()
{
returnn;
}
publicvoidrun()
{
try{
while(true)
{
n=panel.get_x(id);//得到初始位置
if(panel.set_x(id,n))//如果可以生产或者可以消费
{
panel.Update();
++n;
n=n%600;//不断改变X[i],即生产或消费者的横坐标位置
Thread.sleep(4);
panel.set_x(id,n);
}
}
}catch(Exceptione){
//TODO:
handleexception
}
}
}
3.DrawFrame类代码
importjava.awt.Color;
importjava.awt.Container;
importjavax.swing.JFrame;
publicclassDrawFrameextendsJFrame
{
publicDrawPanelpanel;
publicDrawFrame()
{
set
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 生产者 消费者 问题 java 程序设计 报告