这是个读者写者程序~
public class Main {
Factory fa = new Factory();
//主程序
public static void main(String[] args) {
Main mm = new Main();
Writer writer = mm.new Writer();
new Thread(writer).start();
new Thread(writer).start();
new Thread(mm.new Reader()).start();
}
//写者
class Writer implements Runnable {
int max = 1000;//总共写1000次
int i = 0;
@Override
public void run() {
while (true && i < max) {
fa.writeSomething();
++i;
}
}
}
//读者
class Reader implements Runnable {
@Override
public void run() {
while (true) {
fa.readSomething();
}
}
}
class Factory {
List<Integer> repo = new ArrayList<Integer>();//仓库
int max = 100, min = 0, isn = 0;//仓库最大值、最小值、图书编号
//写
public synchronized void writeSomething() {
if (repo.size() == max) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "-write:"
+ isn + "/ Size: " + repo.size());
repo.add(new Integer(isn++));
this.notify();
}
//读
public synchronized void readSomething() {
if (repo.size() == min) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + "-read:"
+ repo.get(0));
repo.remove(0);
this.notifyAll();
}
}
}
一个写者,多个读者的时候这个程序是没问题的
多个写者,一个读者的时候就出问题了,问题在与,仓库最大容量为100,这种情况下会超过100,我感觉问题出在多个写者会相互唤醒,不知道我分析的对不对,所以改了一下writeSomething(),如下:
// 写
public synchronized void writeSomething() {
if (repo.size() >= max) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
System.out.println(Thread.currentThread().getName() + "-write:"
+ isn + "/ Size: " + repo.size());
repo.add(new Integer(isn++));
this.notify();
}
}
这样的确不会出现容量超过100的情况了,但是会死锁,执行不完,,彻底晕了,求解救~~
天蓬老师2017-04-17 11:59:31
writeSomething是synchronized
方法,代表這個方法進入的時候會加鎖,也就是說只要writeSomething不返回,所有其它writeSomething和readSometing都得等著,結果你又在writeSomething裡面wait,所以就死鎖了。
對於reader/writer問題,你需要的其實不是讀寫鎖,而是信號量或條件變數。
怪我咯2017-04-17 11:59:31
"問題在與,倉庫最大容量為100,這種情況下會超過100"
-- 應該是多個寫字者會互相喚醒. 你把wait放在while裡試試:
In other words, waits should always occur in loops, like this one:
synchronized (obj) { while (<condition does not hold>) obj.wait(timeout); ... // Perform action appropriate to condition }
如果一個寫者 被另一個寫者喚醒, 當前的arraylist的size可能還是100. 如果沒有while, 這個寫者接著會把size增為101.
PHPz2017-04-17 11:59:31
你的i一定會到達max,所以writer一定會停,但Reader裡有while(true),所以一定在Thread-2-read:1000時死循環wait,max有一個賦值1000,另一個賦值100,看不懂你的邏輯。