读者写者-【写者优先】

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

 
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值