计算机操作系统实践教学课程报告.docx
- 文档编号:16707104
- 上传时间:2023-07-16
- 格式:DOCX
- 页数:23
- 大小:90.36KB
计算机操作系统实践教学课程报告.docx
《计算机操作系统实践教学课程报告.docx》由会员分享,可在线阅读,更多相关《计算机操作系统实践教学课程报告.docx(23页珍藏版)》请在冰点文库上搜索。
计算机操作系统实践教学课程报告
计算机操作系统实践教学课程报告
题目java编写的信号量解决读者-写者问题
学生李腾龙
学号20094666
指导教师李自强副教授
年级2009级
专业计算机科学与技术
学院信息与工程技术学院
一.程序运行结果图:
a)写者优先时,当一个写进程发送写请求时,不允许新的读者进行读操作,执行完,读者和写者人数均是0。
b)读者优先时,当存在读者时,写者将被延迟。
二.问题解决过程及思路:
a)有两组并发进程:
读操作按钮和写操作按钮分别用(Math.random()*2)+1来随机延迟[1,3)秒的时间实现两组并发进程。
b)问题解决:
i.各类的主要功效:
MainEnter类:
入口类;界面初始化,定义的事件处理器对读、写操作按钮,读写优先切换按钮进行事件处理,用R,W两个字符标示读,写操作,启动读写线程ReadWriteThread.
MainFrame类:
界面类;完成了界面的布局。
ReadWriteThread类:
读写线程类,进行读,写操作。
run()方法,根据R,W的标示,分别执行读线程方法runReader()和写线程方法runWriter().
ReaderCritical类:
读者临界区,用syncgribuzed关键字定义进入临界区方法enterCritical()和离开临界区方法leaveCritical()。
WriterCritical类:
写者临界区。
ii.要求:
允许多个读者同时对文件执行读操作:
解决:
首先,在读者临界区和写者临界区类中,用synchronized关键字定义进入临界区方法enterCritical()和离开临界区方法leaveCritical(),使得同一时间只能有一个ReaderCritical类型的对象调用此方法;其次,定义读写线程ReadWriteThread类中加了对象锁的readStart()方法,进入读者临界区readerCritical.enterCriticalSection(),读者人数自加readerNumber++,if读者人数readerNumber=1时,进入写者临界区writerCritical.enterCriticalSection(),等待写者写结束,之后不再允许写操作;离开读者临界区readerCritical.leaveCriticalSection(),下次如果不是第一个读者,不再进入写锁,直接进行读操作;最后,执行readStop()方法,读者人数readerNumber--,如果读者人数等于0时,离开写者临界区。
iii.要求:
只允许一个写者对文件执行写操作:
解决:
首先,在执行读操作时,一旦没有写者,读者会进入写者临界区writerCritical.enterCriticalSection(),直到最后读者人数等于0时,离开写者临界区,因此,写者执行写操作,进入写者临界区时,需等待,直到没有读者为止;其次,每个写者进行写操作时,必须首先进入写者临界区,而synchronized关键字定义的方法,使得同一时间同步方法不允许被多次调用,这就保证了不可能有两个写者同时工作。
所以,只允许一个写着对文件执行写操作。
iv.要求:
任何写者在完成操作前不允许其他读者或写者工作。
解决:
首先,第一个读者进行读操作时,会进入读者临界区,占去读锁,然后进入写者临界区,而写者未完成写操作时,占去了写锁,使得第一个读者就无法进行读操作,后面因读锁被占去也无法工作;其次,一个写者写操作未完成时,占去了写锁,使得任何其他的写者也无法进行工作。
v.要求:
写者优先时,写者申请写工作后,不再允许新的读者工作;读者优先时,当存在读者时,随后而来的读者都将允许访问文件,写者必须等待。
解决:
首先,写者和读者优先级是通过读写切换按钮每次根据上次优先级更改读写线程类中的静态整型变量priority的值,priority=1时是写者优先,priority=2时是读者优先;其次,在进行写操作的writeStart()方法处理中,if(priority==1)时,即写者优先,进入读者临界区readerCritical.enterCriticalSection(),占去读锁,不再允许其他的新读者工作,然后进入写者临界区,有读者时等待;最后,if(priority==2)时,即读者优先,直接进入写者临界区,有读者时等待,而只要有一个读者正在工作时,其他读者不再需要写锁,直接进行读工作。
c)界面解释。
1.读者人数显示框:
MainFrame对象.JTextField:
在每次读者进行读线程的执行时,发送了读请求后,调用readStart()方法,在每次执行开始读后,MainEnter.frame.textReader.setText((newInteger(readerNumber)).toString()),改变显示框中的值。
runReader()中读完时,调用readStop()方法,将读者人数自减1,MainEnter.frame.textReader.setText((newInteger(readerNumber)).toString()),改变显示框中的值。
2.写者显示框:
同上,只是执行方法分别是,writeStart()和writeStop()。
3.信息显示框:
MainFrame对象.TextArea.在每次执行相应的操作后,就将相应的显示内容,利用MainEnter.frame.textMessage.append(date.getHours()+":
"+date.getMinutes()+":
"+date.getSeconds()+""+serial+"号读线程"+"结束读\n"),将信息附加到显示域的后面,serial变量是每次读,写操作的序号,通过在MainEnter中添加两个成员变量a1,a2,每次自加,在事件处理中将值操作参数,newThread(newReadWriteThread('W',a2++)).start(),传递给读写线程。
三.程序中用到的各个类
第一个类:
主执行类:
packagereaderandwriter;
importjava.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
publicclassMainEnterimplementsActionListener
{
/**
*主界面
*/
staticMainFrameframe;
/**
*读写线程序号
*/
inta1,a2;
publicMainEnter()
{
frame=newMainFrame("信号量解决读者-写者问题",this);
frame.setVisible(true);
}
@Override
publicvoidactionPerformed(ActionEvente)
{
if(e.getSource()==frame.buttonRead)
{
newThread(newReadWriteThread('R',a1++)).start();
}
elseif(e.getSource()==frame.buttonWrite)
{
newThread(newReadWriteThread('W',a2++)).start();
}
elseif(e.getSource()==frame.buttonPriority)
{
if(frame.buttonPriority.getText()=="写优先")
{
ReadWriteThread.setPriority
(2);
frame.buttonPriority.setText("读优先");
}
else
{
ReadWriteThread.setPriority
(1);
frame.buttonPriority.setText("写优先");
}
}
}
publicstaticvoidmain(String[]args)
{
newMainEnter();
}
}
第二个类:
界面类:
//主界面
packagereaderandwriter;
importjava.awt.Color;
importjava.awt.Dimension;
importjava.awt.Font;
importjava.awt.TextArea;
importjava.awt.Toolkit;
importjavax.swing.JButton;
importjavax.swing.JFrame;
importjavax.swing.JLabel;
importjavax.swing.JPanel;
importjavax.swing.JTextField;
publicclassMainFrameextendsJFrame
{
/**
*
*/
privatestaticfinallongserialVersionUID=-6171365492410371629L;
/**
*主面板
*/
JPanelpanel;
/**
*读者和写者人数标签
*/
JLabellabelReader,labelWriter;
/**
*读者和写者人数JTextField;
*/
JTextFieldtextReader,textWriter;
/**
*读写按钮
*/
JButtonbuttonRead,buttonWrite;
/*
*读写优先级按钮,读写优先标签
*/
JButtonbuttonPriority;
JLabellabelPriority;
/**
*信息显示文本域
*/
TextAreatextMessage;
publicMainFrame(Stringstr,MainEntermainEnter)
{
super(str);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Fontfont=newFont("宋体",0,14);
//设置主面板
panel=newJPanel(null);
panel.setBackground(Color.LIGHT_GRAY);
//设置读写标签
labelReader=newJLabel("读者人数");
labelReader.setFont(font);
labelWriter=newJLabel("写者人数");
labelWriter.setFont(font);
//读者和写者显示框
textReader=newJTextField("0");
textReader.setEditable(false);
textWriter=newJTextField("0");
textWriter.setEditable(false);
//设置读写按钮
buttonRead=newJButton("读操作");
buttonRead.setFont(font);
buttonRead.addActionListener(mainEnter);
buttonWrite=newJButton("写操作");
buttonWrite.setFont(font);
buttonWrite.addActionListener(mainEnter);
//读写优先切换按钮,读写优先标签
buttonPriority=newJButton("写优先");
buttonPriority.setFont(font);
buttonPriority.addActionListener(mainEnter);
labelPriority=newJLabel("读写优先切换");
labelPriority.setFont(font);
//显示文本域
textMessage=newTextArea(20,20);
textMessage.setEditable(false);
//控件布局
textMessage.setBounds(10,10,300,200);
labelReader.setBounds(320,15,100,30);
textReader.setBounds(340,50,40,25);
labelWriter.setBounds(320,100,100,30);
textWriter.setBounds(340,135,40,25);
buttonRead.setBounds(60,230,80,30);
buttonWrite.setBounds(180,230,80,30);
labelPriority.setBounds(320,200,100,25);
buttonPriority.setBounds(320,230,80,30);
//控件添加
panel.add(labelPriority);
panel.add(buttonPriority);
panel.add(labelReader);
panel.add(labelWriter);
panel.add(textReader);
panel.add(textWriter);
panel.add(textMessage);
panel.add(buttonRead);
panel.add(buttonWrite);
add(panel);
setSize(430,330);
//在屏幕中央显示
Dimensionscr=Toolkit.getDefaultToolkit().getScreenSize();
Dimensionfra=this.getSize();
if(fra.width>scr.width){
fra.width=scr.width;
}
if(fra.height>scr.height){
fra.height=scr.height;
}
this.setLocation((scr.width-fra.width)/2,
(scr.height-fra.height)/2);
}
}
第三个类:
读写线程类:
packagereaderandwriter;
importjava.util.Date;
publicclassReadWriteThreadimplementsRunnable
{
/**
*读写优先级,1是写者优先,2是读者优先
*/
privatestaticintpriority;
/**
*读者和写者的人数
*/
privatestaticintreaderNumber,writerNumber;
/**
*读写者临界区
*/
privatestaticReaderCriticalreaderCritical;
privatestaticWriterCriticalwriterCritical;
/**
*读写线程标志
*/
privatecharflag;
publicstaticintgetReaderNumber()
{
returnreaderNumber;
}
publicstaticintgetWriterNumber()
{
returnwriterNumber;
}
/**
*读写线程位序
*/
privateintserial;
/**
*延迟的时间
*/
privatedoublelatency;
/**
*持续读写的时间
*/
privatedoublelastTime;
static
{
priority=1;
readerNumber=0;
writerNumber=0;
readerCritical=newReaderCritical();
writerCritical=newWriterCritical();
}
publicstaticvoidsetPriority(intpriority)
{
ReadWriteThread.priority=priority;
}
publicReadWriteThread(charflag,intserial)
{
this.flag=flag;
this.serial=serial;
//随机生成一个1-3秒的延迟时间和10-20持续读写时间
latency=(Math.random()*2)+1;
lastTime=(Math.random()*9)+10;
}
@Override
publicvoidrun()
{
//判断条件,分别执行读写操作
if(flag=='R')
{
runReader();
}
elseif(flag=='W')
{
runWriter();
}
}
//读线程的执行
@SuppressWarnings("deprecation")
publicvoidrunReader()
{
//令线程睡眠指定的时间,模拟延迟时间
try
{
Thread.sleep((long)latency*1000);
}
catch(InterruptedExceptione)
{
e.printStackTrace();
}
Datedate=newDate();
MainEnter.frame.textMessage.append(date.getHours()+":
"+date.getMinutes()+":
"+date.getSeconds()+""+serial+"号读线程"+"发送读请求\n");
//进行读的尝试,及读操作处理
readStart();
//令线程睡眠指定的时间,模拟持续读的时间
try
{
Thread.sleep((long)lastTime*1000);
}
catch(InterruptedExceptione)
{
e.printStackTrace();
}
//结束读的操作方法
readStop();
}
//进入读操作的方法处理
@SuppressWarnings("deprecation")
publicsynchronizedvoidreadStart()
{
//进入读者临界区
readerCritical.enterCriticalSection();
//如果是第一个读者
readerNumber++;
if(readerNumber==1)
{
//有写者时等待
writerCritical.enterCriticalSection();
//记录开始读的时间
Datedate=newDate();
MainEnter.frame.textMessage.append(date.getHours()+":
"+date.getMinutes()+":
"+date.getSeconds()+""+serial+"号读线程"+"开始读\n");
MainEnter.frame.textReader.setText((newInteger(readerNumber)).toString());
//离开读者临界区,使得其他读者进入
readerCritical.leaveCriticalSection();
}
//如果不是第一个读者
else
{
Datedate=newDate();
MainEnter.frame.textMessage.append(date.getHours()+":
"+date.getMinutes()+":
"+date.getSeconds()+""+serial+"号读线程"+"开始读\n");
MainEnter.frame.textReader.setText((newInteger(readerNumber)).toString());
//离开读者临界区,使得其他读者进入
readerCritical.leaveCriticalSection();
}
}
//结束读操作方法
@SuppressWarnings("deprecation")
publicvoidreadStop()
{
readerNumber--;
Datedate=newDate();
MainEnter.frame.textMessage.append(date.getHours()+":
"+date.getMinutes()+":
"+date.getSeconds()+""+serial+"号读线程"+"结束读\n");
MainEnter.frame.textReader.setText((newInteger(readerNumber)).toString());
//没有读者时,唤醒写者
if(readerNumber==0)
{
writerCritical.leaveCriticalSection();
}
}
//写线程的执行
@SuppressWarnings("deprecation")
publicvoi
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机 操作系统 实践 教学 课程 报告
![提示](https://static.bingdoc.com/images/bang_tan.gif)