Rumah > Soal Jawab > teks badan
这是个读者写者程序~
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,看不懂你的逻辑。