java 读者写者问题

 读者—写者问题(Readers-Writers problem)也是一个经典的并发程序设计问题,是经常出现的一种同步问题。计算机系统中的数据(文件、记录)常被多个进程共享,但其中某些进程可能只要求读数据(称为读者Reader);另一些进程则要求修改数据(称为写者Writer)。就共享数据而言,Reader和Writer是两组并发进程共享一组数据区,要求:
(1)允许多个读者同时执行读操作;
(2)不允许读者、写者同时操作;

(3)不允许多个写者同时操作。一次只能一个写者  

实现原理:使用Semapore 信号量 分别表示读者和写者的信号量 读者可以多个同时读,写者只能有一个可以写,使用AtomicInteger定义 readerCount 和writerCount 表示当前读者和当前写者的数量 

package test;

import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;

public class ThreadSync {

	private static ThreadSync thrdsync;
	private static Thread t1, t2, t3, t4, t5;
	private static final Random rand = new Random();
	private static Semaphore sm = new Semaphore(2);// 信号量 允许2个线程 true表示先进先出
	private static Semaphore wsm = new Semaphore(1);// 信号量 允许1个线程
	String text = "Beginning of the Book";// 代表书本
	AtomicInteger readerCount = new AtomicInteger(0); // 记录当前读者数量
	AtomicInteger writerCount = new AtomicInteger(0); // 记录当前写者数量

	// 随机休眠一定时间
	private void busy() {
		try {
			Thread.sleep(rand.nextInt(1000) + 1000);
		} catch (InterruptedException e) {
		}
	}

	// 写函数
	void write(String sentence) {
		System.out.println(Thread.currentThread().getName()
				+ " started to WRITE");
		text += "\n" + sentence;
		System.out.println(text);
		System.out.println("End of Book\n");
		System.out.println(Thread.currentThread().getName()
				+ " finished WRITING");
	}

	// 读函数
	void read() {

		System.out.println("\n" + Thread.currentThread().getName()
				+ " started to READ");
		// System.out.println(text);
		// System.out.println("End of Book\n");

	}

	// 写者
	private class Writer implements Runnable {

		ThreadSync ts;

		Writer(ThreadSync ts) {
			super();
			this.ts = ts;

		}

		public void run() {
			while (true) {
				if (readerCount.get() == 0) { // 当没有读者时才 可以写
					try {
						//System.out.println("write---readerCount= "+readerCount.get());
						//System.out.println("write---writerCount= "+writerCount.get());
						wsm.acquire(); // 信号量获取允许
						writerCount.getAndIncrement();
					} catch (InterruptedException ex) {
						Logger.getLogger(ThreadSync.class.getName()).log(
								Level.SEVERE, null, ex);
					}
					String new_sentence = new String("\tnew line in Book");
					busy();
					ts.write(new_sentence);
					wsm.release(); // 信号量释放
					writerCount.getAndDecrement();

					busy();

				}
			} // of while
		}
	}

	// 读者
	private class Reader implements Runnable {

		ThreadSync ts;

		Reader(ThreadSync ts) {
			super();
			this.ts = ts;

		}

		public void run() {
			while (true) {
				if (writerCount.get() == 0) { // 没有写者时 才可以读
					try {
						//System.out.println("Read---readerCount= "+readerCount.get());
						//System.out.println("Read---writerCount= "+writerCount.get());
						sm.acquire(); // 读者获取允许
						readerCount.getAndIncrement();
					} catch (InterruptedException ex) {
						Logger.getLogger(ThreadSync.class.getName()).log(
								Level.SEVERE, null, ex);
					}
					// System.out.print(t);

					ts.read();
					busy();
					System.out.println(Thread.currentThread().getName()
							+ " end of read");
					sm.release(); // 释放允许
					readerCount.getAndDecrement();
					busy();
				}
			} // of while
		}
	}

	// 创建两个读者 一个写者
	public void startThreads() {
		ThreadSync ts = new ThreadSync();
		t1 = new Thread(new Writer(ts), "Writer # 1");
		t2 = new Thread(new Writer(ts), "Writer # 2");
		t3 = new Thread(new Reader(ts), "Reader # 1");
		t4 = new Thread(new Reader(ts), "Reader # 2");
		// t5 = new Thread(new Reader(ts), "Reader # 3");
		t1.start();
		t2.start();
		t3.start();
		t4.start();
		// t5.start();
	}

	public static void main(String[] args) {
		thrdsync = new ThreadSync();
		System.out.println("Lets begin...\n");
		thrdsync.startThreads();
	}
}

输出结果:

Lets begin...


Writer # 1 started to WRITE
Beginning of the Book
new line in Book
End of Book


Writer # 1 finished WRITING


Reader # 1 started to READ
Writer # 2 started to WRITE
Beginning of the Book
new line in Book
new line in Book
End of Book


Writer # 2 finished WRITING


Reader # 2 started to READ
Reader # 1 end of read
Reader # 2 end of read
Writer # 2 started to WRITE
Beginning of the Book
new line in Book
new line in Book
new line in Book
End of Book


Writer # 2 finished WRITING
Writer # 1 started to WRITE
Beginning of the Book
new line in Book
new line in Book
new line in Book
new line in Book
End of Book


Writer # 1 finished WRITING


Reader # 1 started to READ


Reader # 2 started to READ
Reader # 1 end of read
Reader # 2 end of read


上面的输出结果 出现一个问题.读者在读的过程中写者开始写 .其实是由于调用 输出函数后产生的. 希望有哪位大神可以帮忙改改,让代码变得更好 

发布了34 篇原创文章 · 获赞 45 · 访问量 22万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章