スレッドのマルチスレッドおよびプロセス間通信を学習しようとしています。典型的なproducer-consumer問題を実装しました。しかし、出力は理想的にスレッドで作業している間にはならないかなり連続的です。Javaスレッド|プロデューサー消費者:コードに何が問題なのですか?
ので、ここで完全なコードで、[OK]を:今、私はプログラムを実行すると、プロデューサーのスレッドがある
public class Consumer implements Runnable {
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
for(int i=1;i<=10;i++){
ProducerConsumerSimulation.simulation.consume();
}
}
}
:
public class ProducerConsumerSimulation {
public static ProducerConsumerSimulation simulation = new ProducerConsumerSimulation();
private Queue<Integer> sharedQueue = new LinkedList<Integer>();
private int MAX_LIMIT = 10;
public void produce(int i){
synchronized (sharedQueue) {
while(true){
while(sharedQueue.size()==MAX_LIMIT){
try {
sharedQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
sharedQueue.add(i);
System.out.println("Produced: "+i);
sharedQueue.notifyAll();
return;
}
}
}
public void consume() {
synchronized (sharedQueue) {
while (true) {
while (sharedQueue.isEmpty()) {
try {
sharedQueue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int i = sharedQueue.remove();
System.out.println("Consumed: " + i);
sharedQueue.notifyAll();
return;
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
for(int i=1;i<=5;i++){
Runnable p = new Producer();
Thread prod = new Thread(p);
prod.start();
}
for(int i=1;i<=5;i++){
Runnable c = new Consumer();
Thread con = new Thread(c);
con.start();
}
}
}
生産者スレッド:
public class Producer implements Runnable {
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
for(int i=1;i<=10;i++){
ProducerConsumerSimulation.simulation.produce(i);
}
}
}
消費者スレッド消費者より常に最初に走っています。複数のプロデューサ/コンシューマを作成しても結果は同じです。以下は、1つのプロデューサとシングル・コンシューマに出力されます:
Produced: 1
Produced: 2
Produced: 3
Produced: 4
Produced: 5
Produced: 6
Produced: 7
Produced: 8
Produced: 9
Produced: 10
Consumed: 1
Consumed: 2
Consumed: 3
Consumed: 4
Consumed: 5
Consumed: 6
Consumed: 7
Consumed: 8
Consumed: 9
Consumed: 10
誰かがここでの挙動を説明できますか?私はここで多くの答えを行ったが、間違って実装されているかどうかを理解したい。
ループ全体が同期ブロックにあります。 1つのスレッドは、他のスレッドが完全に終了するまでスタックされます。 – shmosel
@shmosel私もそうだと思っていましたが、実際には、ループ内にリターンがあり、このループは完全に役に立たなくなりました(しかし非常に混乱します)。 –
@JBNizet良い点。おそらくwait/notifyループパターンの誤解。 – shmosel