Я пытаюсь решить проблему производителя с потоками в java, но код не будет работать параллельно или параллельно. Производитель всегда заполняет буфер полностью, прежде чем потребитель начнет потреблять, и я не понимаю почему. Точка пытается это сделать, используя только синхронизированные блоки, wait() и notify().Попытка решить потребитель-производитель в java с многопоточным
Главная:
String [] data = {"Fisk", "Katt", "Hund", "Sau", "Fugl", "Elg", "Tiger",
"Kameleon", "Isbjørn", "Puma"};
ProducerConsumer pc = new ProducerConsumer(5);
Thread[] thrds = new Thread[2];
thrds[0] = new Thread(new MyThread1(pc, data)); // producer
thrds[1] = new Thread(new MyThread2(pc)); // consumer
thrds[0].start();
thrds[1].start();
for(int i = 0; i < 2; i++) { // wait for all threads to die
try {
thrds[i].join();
}
catch (InterruptedException ie) {}
}
System.exit(0);
ProducerConsumer.java:
import java.util.LinkedList;
import java.util.Queue;
public class ProducerConsumer implements Runnable {
private int bufferSize;
private Queue<String> buffer;
public ProducerConsumer(int size) {
bufferSize = size;
buffer = new LinkedList<String>();
}
public void produce(String item) throws InterruptedException {
synchronized(buffer) {
while (buffer.size() >= bufferSize) {
try {
System.out.println("Full buffer. Waiting for consumer...");
buffer.wait();
}catch (Exception e) {}
}
buffer.add(item);
System.out.println("Producer is putting " + item + " in the buffer");
buffer.notify();
}
}
public void consume() throws InterruptedException {
synchronized (buffer) {
while (buffer.size() == 0) {
try {
System.out.println("Empty buffer. Waiting for production...");
buffer.wait();
}catch (Exception e) {}
}
System.out.println("Consumer is consuming " + buffer.remove() + ".");
buffer.notify();
}
}
@Override
public void run() {
}
}
MyThread1:
/*
* PRODUCER - Thread
*/
public class MyThread1 implements Runnable {
private String [] data;
private ProducerConsumer pc;
public MyThread1(ProducerConsumer pc, String [] data) {
this.pc = pc;
this.data = data;
}
@Override
public void run() {
for (int i = 0; i < data.length; i++) {
try {
pc.produce(data[i]);
} catch (InterruptedException ex) {}
}
}
}
MyThread2:
// ПОТРЕБИТЕЛЯ - Thread
public class MyThread2 implements Runnable{
private ProducerConsumer pc;
public MyThread2(ProducerConsumer pc) {
this.pc = pc;
}
//Run consume
@Override
public void run() {
while (true) {
try {
pc.consume();
Thread.sleep(2);
}
catch(InterruptedException e) {}
}
}
}
Я думаю из-за 'synchronized (buffer)' –
A) Это какое-то назначение или у вас есть другие причины не использовать [BlockingQueue] (https://docs.oracle.com/javase/7/ документы/API/Java/Util/параллельный/BlockingQueue.html)? B) нет кода для предотвращения того, что производитель работает так быстро, как есть. Если вы хотите, чтобы это произошло, возможно, дайте ему спать или так? Нити не имеют заданного времени синхронизации, и первый запуск потока может завершиться до того, как вы начнете второй. – zapl
И почему ProducerConsumer реализует Runnable? –