javamultithreadinginfinite-loopproducer-consumermonitors

why does my program get stuck sometimes?


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());}
        }
    }
}

Solution

  • I can not repoduce the stuck situation. But I found some other problems in your code:

    Two solve these problems, I think you need:

    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