java实现读者写者问题(写着优先)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验一实验报告
学号:20092128 姓名:徐卓远
实验序号:1
实验名称:用信号量来实现读者-写者问题
实验目的:理解进程同步与互斥的概念,掌握用信号量来实现进程的同步与互斥。
实验设计及实现:
为了实现读者和写者的读写过程,将每个读者和每个写者作为了一个单独的线程,所以设置了两个类,一个是读者类Reader,一个是写者类Writer.以读者类为例:
一个读者的动作过程为由睡眠->等待->开始读->结束读->睡眠的一个循环过程,而一个写者的动作过程也为此.
读者调用方法napping()进行等待,调用startRead()方法开始读,最后在调用endReading()方法结束读入,释放运行空间.写者同读者.
但是为了实现读者写者之间的写-写互斥,读-写互斥,读-读允许,需要另外一个类Database,类中分别用关于读者的方法和写者的方法来控制读写之间的这种关系.
首先要实现睡眠的方法napping(),读者和写者在睡眠过程都应该是一样的,只是他们睡眠的时间不同,所以只需写出一个方法:
public static void napping() {
int sleepTime = (int) (NAP_TIME * Math.random()); try {
Thread.sleep(sleepTime * 1000);
} catch (Exception e) {
e.printStackTrace();
}
}
在方法中,控制线程休眠随机的时间,由于每个读者或写者都是一个线程,而每个读者或写者他们工作休眠的时间都不一定相同,他们请求工作的时间也不一定相同,所以取了随机时间其次设置了读者的两个方法,开始读和结束读,由于这只是个模拟读写问题,所以只需要知道结果就行,就不用显示出他是怎么读的.
在开始读中,当有写者在写时,读者需要等待wait(),在没有人在工作时,如果有写者和读者同时请求,那么就让写者先进,这是写者优先.所以这就归纳于一种情况, 当读者布尔变量dbReading为FALSE时,如果有需要工作的写者,那么读者就等待.
当读者请求读入后,计数有多少读者需要工作的变量readerCount +1,如果这是第一个进入工作的读者就需要将显示是否有读者在工作的读者布尔变量变为TRUE.
public synchronized int startRead() {
if (dbReading == false) {
while (writerCount > 0) {
try {
System.out.println("reader is waiting");
wait();
} catch (Exception e) {
System.out.println(e.toString());
e.printStackTrace();
}
}
}
++readerCount;
if (readerCount == 1) {
dbReading = true;
}
return readerCount;
}
读结束时,计数需要读的读者数-1,然后释放出空间给需要工作的人.
public synchronized int endReading() {
--readerCount;
if (readerCount == 0) {
dbReading = false;
}
notifyAll();//释放出空间
System.out.println("one reader is done, reading.
Count=" + readerCount);
return readerCount;
}
第三,编写关于写者的开始写和结束写方法,在开始写方法中,首先要将计数需要写的变量writerCount+1,写者如果有读者或者有写者正在工作,那么就等待,如果没有就直接进入写,然后表示是否有写者在写的布尔变量dbWriting变为TRUE
public synchronized void startWriting() {//控制写者开始进入写
++writerCount;
while (dbReading == true || dbWriting == true) {
try {
System.out.println("Writer is waiting");
wait();
} catch (Exception e) {
System.out.println(e.toString());
}
}
dbWriting = true;
}
结束时只需将writerCount-1和dbWriting为FALSE,然后释放出空间.
public synchronized void endWriting() {//控制写者结束写入
--writerCount;
dbWriting = false;
System.out.println("one writer is done, writing.
Count=" + writerCount);
notifyAll();
}
源代码及程序流程图
主类:
package rw;
/**
*
* @author xzy
*/
public class Main {