1. 实现原理
首先设计两个线程,一个读者线程,一个写者线程,两个线程
读者写者问题是这样一种情况,就是允许对资源进行两种类型的操作(读和写)。
而写操作是排他的(排斥读者,同样排斥其他写者),读操作是共享的(多个读者可读,排斥写者)。
这就存在两种策略:
1.读者优先(强读者同步Strong reader synchronization):总是给读者优先权,只要写者当前没有进行写操作,读者就能获得访问权。这种情况存在于读者很多,写者不经常更新的时候使用,如图书馆参考数据库采用读者优先比较好。
2.写者优先(强写者同步Strong writer synchronization):通常把优先权交给写者,而将读者延迟到所有等待的或活动的写者都完成了为止。这种情况存在于经常更新的系统,而读者对最新信息感兴趣,如机票预定系统,写者进行机票价格的更新,读者获取当前机票价。
简单的说就是资源没人占用,则谁先到先用,用的时候上锁,读者上读者锁,写者上写者锁。
1.假设先来的读者上读者锁,接下来再a)来读者,可以读资源,将读者计数器+1,b)来写者则等待(阻塞或者不断尝试)直到读者释放资源(计数器为0),选取一个写者开始写
2.若先来的是写者上写者锁,这时候又来了比如N个读者,M个写者等待(写者锁排他),
这时候要是a)读者优先,则写者释放锁后,让等候的N个读者先读(其他写者接着等着等,变为情况1),
这时候要是b)写者优先,则写者释放锁后,让等候的M个中的一个写者写,读者接着等待直到没有写者为止(等的的M个写者全写完还有中途再来的写者)。
所以 是讨论读者优先还是写者优先的前提是 :先来的是写者上写者锁
读者写者问题本身就存在着饿死的情况。
2. 上代码:
缓冲区类
package com.bankht.writerReader;
/**
* @author zhuyong
* @创建时间:2012-6-7 下午02:32:02
*
* @类说明 :缓冲区
*/
public class CubbyHole {
private int readerCount;// 读者数
private int writerCount;// 写者数
private boolean dbReading;// 读信号量
private boolean dbWriting;// 写信号量
public CubbyHole() {
readerCount = 0;
writerCount = 0;
dbReading = false;
dbWriting = false;
}
public static void napping() {// 线程睡眠,不消耗CPU资源
try {
Thread.sleep((int) (Math.random() * 4000));
} catch (Exception e) {
}
}
public synchronized int startRead() {// 开始读
while (writerCount > 0) {
try {
System.out.println("reader is waiting");
wait();// 等待写者发出notify
} catch (Exception e) {
}
}
++readerCount;
if (readerCount >= 1) {
dbReading = true;
}
return readerCount;
}
public synchronized int endReading() {// 结束读
--readerCount;
if (readerCount == 0) {
dbReading = false;
}
notifyAll();
System.out.println("one reader is done reading. Count=" + readerCount);
return readerCount;
}
public synchronized void startWriting() {// 开始写
++writerCount;
while (dbReading == true || dbWriting == true) {
try {
System.out.println("Writer is waiting");
wait();// 等待读者发出notify
} catch (Exception e) {
}
}
dbWriting = true;
}
public synchronized void endWriting() {// 结束写
--writerCount;
dbWriting = false;
System.out.println("one writer is done writing. Count=" + writerCount);
notifyAll();
}
}
读者类:
package com.bankht.writerReader;
/**
* @author zhuyong
* @创建时间:2012-6-7 下午02:32:51
*
* @类说明 :读者
*/
public class Reader extends Thread {// 定义读线程,继承Thread类,重写run方法
private CubbyHole C;
private int readerNum;
public Reader(int r, CubbyHole db) {
readerNum = r;
C = db;
}
public void run() {
int c;
while (true) {
System.out.println("reader " + readerNum + " is sleeping");
CubbyHole.napping();
System.out.println("reader " + readerNum + " wants to read");
c = C.startRead();
System.out.println("reader " + readerNum + " is reading. Count="
+ c);
CubbyHole.napping();
c = C.endReading();
System.out.println("It is reader " + readerNum
+ " who has done reading. count=" + c);
}
}
}
写者类:
package com.bankht.writerReader;
/**
* @author zhuyong
* @创建时间:2012-6-7 下午02:34:36
*
* @类说明 :写者
*/
public class Writer extends Thread {// 定义写线程
private CubbyHole C;
private int writerNum;
public Writer(int w, CubbyHole db) {
writerNum = w;
C = db;
}
public void run() {
while (true) {
System.out.println("Writer " + writerNum + " is sleeping");
CubbyHole.napping();
System.out.println("Writer " + writerNum + " wants to write");
C.startWriting();
System.out.println("Writer " + writerNum + " is writing");
CubbyHole.napping();
C.endWriting();
System.out.println("It is Writer " + writerNum
+ " who has done writing .");
}
}
}
测试类:
package com.bankht.writerReader;
/**
* @author zhuyong
* @创建时间:2012-6-7 下午02:31:32
*
* @类说明 :
*/
public class WriterReader {
public static void main(String[] args) {
testWriterReader();
}
public static void testWriterReader() {
CubbyHole db = new CubbyHole();// 缓冲区
Reader r1 = new Reader(1, db);// 读者
Reader r2 = new Reader(2, db);
Reader r3 = new Reader(3, db);
Reader r4 = new Reader(4, db);
Writer w1 = new Writer(1, db);// 写者
Writer w2 = new Writer(2, db);
r1.start();
r2.start();
r3.start();
w1.start();
r4.start();
w2.start();
}
}
运行结果:
reader 1 is sleeping
reader 3 is sleeping
reader 2 is sleeping
reader 4 is sleeping
Writer 1 is sleeping
Writer 2 is sleeping
Writer 1 wants to write
Writer 1 is writing
reader 1 wants to read
reader is waiting
reader 2 wants to read
reader is waiting
one writer is done writing. Count=0
It is Writer 1 who has done writing .
reader 1 is reading. Count=2
reader 2 is reading. Count=1
Writer 1 is sleeping
reader 3 wants to read
reader 3 is reading. Count=3
Writer 1 wants to write
Writer is waiting
Writer 2 wants to write
Writer is waiting
one reader is done reading. Count=2
Writer is waiting
It is reader 1 who has done reading. count=2
Writer is waiting
reader 1 is sleeping
reader 4 wants to read
reader is waiting
one reader is done reading. Count=1
It is reader 2 who has done reading. count=1
reader is waiting
reader 2 is sleeping
Writer is waiting
Writer is waiting
reader 1 wants to read
reader is waiting
one reader is done reading. Count=0
It is reader 3 who has done reading. count=0
reader is waiting
reader 3 is sleeping
Writer is waiting
Writer 2 is writing
reader is waiting
reader 2 wants to read
reader is waiting
one writer is done writing. Count=1
reader is waiting
It is Writer 2 who has done writing .
reader is waiting
Writer 2 is sleeping
reader is waiting
Writer 1 is writing
reader 3 wants to read
reader is waiting
Writer 2 wants to write
Writer is waiting
one writer is done writing. Count=1
It is Writer 1 who has done writing .
reader is waiting
Writer 2 is writing
reader is waiting
Writer 1 is sleeping
reader is waiting
reader is waiting