私は、1つのスレッドがメッセージをVectorに入れ、もう1つがメッセージをVectorから取り除く、Producer/Consumerの問題の解決策を作成しようとしています。なぜコンシューマスレッドはVectorからメッセージを削除できないのですか?
import java.util.Vector;
public class Producer implements Runnable {
static final int MAXQUEUE = 5;
private Vector<String> messages;
public Producer(Vector<String> messages) {
super();
this.messages = messages;
}
@Override
public void run() {
try {
while (true)
putMessage();
} catch (InterruptedException e) {
}
}
private synchronized void putMessage() throws InterruptedException {
while (messages.size() == MAXQUEUE) {
wait();
}
messages.addElement(new java.util.Date().toString());
System.out.println("put message");
notifyAll();
}
public static void main(String args[]) {
Vector<String> messages = new Vector<String>();
new Thread(new Producer(messages)).start();
new Thread(new Consumer(messages)).start();
}
}
class Consumer implements Runnable{
public Consumer(Vector<String> messages) {
super();
this.messages = messages;
}
private Vector<String> messages;
public synchronized String getMessage() throws InterruptedException {
notifyAll();
while (messages.size() == 0) {
wait();//By executing wait() from a synchronized block, a thread gives up its hold on the lock and goes to sleep.
}
String message = (String) messages.firstElement();
messages.removeElement(message);
return message;
}
@Override
public void run() {
try {
while (true) {
String message = getMessage();
System.out.println("Got message: " + message);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
プログラムを実行しているときはいつでも、メッセージを5回印刷しています。私はnotifyAll()の後でさえ、消費者にロックを与えていないことを理解していません。
これは問題ではないかもしれませんが、mainメソッドを別のドライバクラスに入れてみてください。 –
あなたはそれがいっぱいになるまでできるだけ早く入れていますが、プロデューサの呼び出しがwait()になるまで消費者がロックを取得できなければ私は驚くことはありません。 –
BTW BlockingQueueを使用すると、プロデューサがコンシューマをロックアウトしないので、はるかに簡単で効率的になります。つまり、追加と削除を同時に行うことができます。 –