So I have written a bounded buffer problem in java using monitors and I can't figure out whats wrong with my program. sometimes it keeps running in an infinite loop just before the end of the third loop. Most of the times it runs perfectly. the program is simple and about one producer and multiple consumers. I would appreciate any help. here is a link to my github where you can find the whole code. the full code
BoundedBuffer
public class BoundedBuffer {
public BoundedBuffer ()
{
int numWorms = 10;
int numBirds = 5;
Dish dish = new Dish (numWorms);
Parent parent = new Parent(dish);
parent.start();
Child child[] = new Child[numBirds];
for (int i = 0; i < numBirds; i++)
{
child[i] = new Child (dish);
child[i].start();
}
for (int i = 0; i < numBirds; i++)
{
try {child[i].join();}
catch (Exception ie) {System.out.println (ie.getMessage());}
}
System.out.println("bids done eating :D");
}
}
Dish
public class Dish
{
int worms;
int copy;
public Dish (int worms)
{
this.worms = worms;
copy = worms;
}
public synchronized void eat ()
{
if (worms <= 0)
{
waitForFull();
}
worms --;
System.out.println("Bird " + Thread.currentThread().getName() + " has
eaten."
+ " The number of worms left is " + worms);
}
public synchronized void fill()
{
if (worms > 0)
{
waitForEmpty();
}
worms = copy;
System.out.println ("Parent filled the dish");
notifyAll();
}
public synchronized void waitForEmpty ()
{
while (worms > 0)
{
notifyAll();
try {wait();}
catch (Exception ie) {System.out.println (ie.getMessage());}
}
}
public synchronized void waitForFull ()
{
while (worms <= 0)
{
notifyAll();
try {wait();}
catch (Exception ie) {System.out.println (ie.getMessage());}
}
}
}
I can not repoduce the stuck
situation. But I found some other problems in your code:
Parent
set done = 1
immediatlly after three loops, at this
time, there are still Worms
in the Dish
.waitForEmpty
and fill
are not automatic, which may result in
some inconstency.waitForFull
and eat
are not automatic, which may result in
some inconstency.Two solve these problems, I think you need:
waitForEmpty
and fill
as a single method, as well as waitForFull
and eat
.shutdown
and isTerminate
as signal. Parent
will shutdown
the Dish
, while the last Child
will terminate
the Dish
. Here is the code:
Main
public class Main {
public static void main(String[] args) {
new BoundedBuffer ();
}
}
BoundedBuffer
public class BoundedBuffer {
public BoundedBuffer () {
int numWorms = 10;
int numBirds = 5;
Dish dish = new Dish (numWorms);
Parent parent = new Parent(dish);
parent.start();
Child child[] = new Child[numBirds];
for (int i = 0; i < numBirds; i++) {
child[i] = new Child (dish);
child[i].start();
}
for (int i = 0; i < numBirds; i++) {
try {child[i].join();}
catch (Exception ie) {System.out.println (ie.getMessage());}
}
System.out.println("bids done eating :D");
}
}
Dish
public class Dish {
int worms;
int copy;
boolean shutDown;
boolean isTerminated;
public Dish (int worms) {
this.worms = worms;
copy = worms;
}
public synchronized void waitForEmptyToFill() {
while (worms > 0) {
try {
notifyAll();
wait();
} catch (Exception ie) {
System.out.println (ie.getMessage());
}
}
worms = copy;
System.out.println ("Parent filled the dish");
notifyAll();
}
public synchronized void waitForFullToEat () {
while (worms <= 0 && !isTerminated()) {
try {
notifyAll();
wait();
} catch (Exception ie) {
System.out.println (ie.getMessage());
}
}
if (worms > 0) {
worms--;
System.out.println("Bird " + Thread.currentThread().getName() + " has eaten."
+ " The number of worms left is " + worms);
if (worms == 0 && isShutDown()) {
setTerminated(true);
notifyAll();
}
}
}
public synchronized boolean isShutDown() {
return shutDown;
}
public synchronized void setShutDown(boolean shutDown) {
this.shutDown = shutDown;
}
public synchronized boolean isTerminated() {
return isTerminated;
}
public synchronized void setTerminated(boolean terminated) {
isTerminated = terminated;
}
}
Parent
public class Parent extends Thread {
private Dish dish;
public Parent (Dish dish) {
this.dish = dish;
}
public void run() {
for (int i = 0; i < 3; i++) {
dish.waitForEmptyToFill();
}
dish.setShutDown(true);
}
}
Child
public class Child extends Thread {
private Dish dish;
public Child (Dish dish)
{
this.dish = dish;
}
public void run () {
while (!dish.isTerminated()) {
dish.waitForFullToEat();
try {
sleep(100);
} catch (Exception ie) {
System.out.println (ie.getMessage());
}
}
}
}
OutPut:
Bird Thread-4 has eaten. The number of worms left is 9
Bird Thread-3 has eaten. The number of worms left is 8
Bird Thread-2 has eaten. The number of worms left is 7
Bird Thread-5 has eaten. The number of worms left is 6
Bird Thread-1 has eaten. The number of worms left is 5
Bird Thread-2 has eaten. The number of worms left is 4
Bird Thread-3 has eaten. The number of worms left is 3
Bird Thread-4 has eaten. The number of worms left is 2
Bird Thread-1 has eaten. The number of worms left is 1
Bird Thread-5 has eaten. The number of worms left is 0
Parent filled the dish
Bird Thread-4 has eaten. The number of worms left is 9
Bird Thread-5 has eaten. The number of worms left is 8
Bird Thread-3 has eaten. The number of worms left is 7
Bird Thread-1 has eaten. The number of worms left is 6
Bird Thread-2 has eaten. The number of worms left is 5
Bird Thread-4 has eaten. The number of worms left is 4
Bird Thread-5 has eaten. The number of worms left is 3
Bird Thread-1 has eaten. The number of worms left is 2
Bird Thread-2 has eaten. The number of worms left is 1
Bird Thread-3 has eaten. The number of worms left is 0
Parent filled the dish
Bird Thread-1 has eaten. The number of worms left is 9
Bird Thread-5 has eaten. The number of worms left is 8
Bird Thread-3 has eaten. The number of worms left is 7
Bird Thread-2 has eaten. The number of worms left is 6
Bird Thread-4 has eaten. The number of worms left is 5
Bird Thread-2 has eaten. The number of worms left is 4
Bird Thread-3 has eaten. The number of worms left is 3
Bird Thread-1 has eaten. The number of worms left is 2
Bird Thread-5 has eaten. The number of worms left is 1
Bird Thread-4 has eaten. The number of worms left is 0
Parent filled the dish
Bird Thread-2 has eaten. The number of worms left is 9
Bird Thread-3 has eaten. The number of worms left is 8
Bird Thread-1 has eaten. The number of worms left is 7
Bird Thread-5 has eaten. The number of worms left is 6
Bird Thread-4 has eaten. The number of worms left is 5
Bird Thread-2 has eaten. The number of worms left is 4
Bird Thread-3 has eaten. The number of worms left is 3
Bird Thread-1 has eaten. The number of worms left is 2
Bird Thread-5 has eaten. The number of worms left is 1
Bird Thread-4 has eaten. The number of worms left is 0
bids done eating :D