(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
上面的輸出結果 出現一個問題.讀者在讀的過程中寫者開始寫 .其實是由於調用 輸出函數後產生的. 希望有哪位大神可以幫忙改改,讓代碼變得更好