JAVA-18228 Potential issue in "Producer-Consumer Problem With Example… (#13582)

JAVA-18228 Potential issue in "Producer-Consumer Problem With Example in Java" article
This commit is contained in:
timis1 2023-03-22 10:26:22 +02:00 committed by GitHub
parent 4fdc89218c
commit 163056b1ca
3 changed files with 32 additions and 31 deletions

View File

@ -2,11 +2,9 @@ package com.baeldung.producerconsumer;
public class Consumer implements Runnable { public class Consumer implements Runnable {
private final DataQueue dataQueue; private final DataQueue dataQueue;
private volatile boolean runFlag;
public Consumer(DataQueue dataQueue) { public Consumer(DataQueue dataQueue) {
this.dataQueue = dataQueue; this.dataQueue = dataQueue;
runFlag = true;
} }
@Override @Override
@ -15,22 +13,23 @@ public class Consumer implements Runnable {
} }
public void consume() { public void consume() {
while (runFlag) { while (dataQueue.runFlag) {
Message message; synchronized (this) {
if (dataQueue.isEmpty()) { while (dataQueue.isEmpty() && dataQueue.runFlag) {
try { try {
dataQueue.waitOnEmpty(); dataQueue.waitOnEmpty();
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
break;
}
}
if (!dataQueue.runFlag) {
break; break;
} }
Message message = dataQueue.remove();
dataQueue.notifyAllForFull();
useMessage(message);
} }
if (!runFlag) {
break;
}
message = dataQueue.remove();
dataQueue.notifyAllForFull();
useMessage(message);
} }
System.out.println("Consumer Stopped"); System.out.println("Consumer Stopped");
} }
@ -45,7 +44,7 @@ public class Consumer implements Runnable {
} }
public void stop() { public void stop() {
runFlag = false; dataQueue.runFlag = false;
dataQueue.notifyAllForEmpty(); dataQueue.notifyAllForEmpty();
} }
} }

View File

@ -9,6 +9,8 @@ public class DataQueue {
private final Object FULL_QUEUE = new Object(); private final Object FULL_QUEUE = new Object();
private final Object EMPTY_QUEUE = new Object(); private final Object EMPTY_QUEUE = new Object();
public boolean runFlag = true;
DataQueue(int maxSize) { DataQueue(int maxSize) {
this.maxSize = maxSize; this.maxSize = maxSize;
} }

View File

@ -2,13 +2,11 @@ package com.baeldung.producerconsumer;
public class Producer implements Runnable { public class Producer implements Runnable {
private final DataQueue dataQueue; private final DataQueue dataQueue;
private volatile boolean runFlag;
private static int idSequence = 0; private static int idSequence = 0;
public Producer(DataQueue dataQueue) { public Producer(DataQueue dataQueue) {
this.dataQueue = dataQueue; this.dataQueue = dataQueue;
runFlag = true;
} }
@Override @Override
@ -17,21 +15,23 @@ public class Producer implements Runnable {
} }
public void produce() { public void produce() {
while (runFlag) { while (dataQueue.runFlag) {
Message message = generateMessage(); synchronized (this) {
while (dataQueue.isFull()) { while (dataQueue.isFull() && dataQueue.runFlag) {
try { try {
dataQueue.waitOnFull(); dataQueue.waitOnFull();
} catch (InterruptedException e) { } catch (InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
break;
}
}
if (!dataQueue.runFlag) {
break; break;
} }
Message message = generateMessage();
dataQueue.add(message);
dataQueue.notifyAllForEmpty();
} }
if (!runFlag) {
break;
}
dataQueue.add(message);
dataQueue.notifyAllForEmpty();
} }
System.out.println("Producer Stopped"); System.out.println("Producer Stopped");
} }
@ -47,7 +47,7 @@ public class Producer implements Runnable {
} }
public void stop() { public void stop() {
runFlag = false; dataQueue.runFlag = false;
dataQueue.notifyAllForFull(); dataQueue.notifyAllForFull();
} }
} }