您的位置:首页 > 编程语言 > Java开发

java 读者写者问题

2015-09-28 20:07 477 查看
 读者—写者问题(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

上面的输出结果 出现一个问题.读者在读的过程中写者开始写 .其实是由于调用 输出函数后产生的. 希望有哪位大神可以帮忙改改,让代码变得更好 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: