Search code examples
javamultithreadingwaitnotifydining-philosopher

notifyAll() not awakening processes


I'm programming a little Java program where I need to create threads (philosophers in my code), and these philosophers need to change of state between thinking, hungry and eating. I'm not that far into the project and I have the next problem:

public class NewMain {

    static Philosopher [] p;

    public static void main(String[] args) {
        p = new Philosopher[5];

        p[0] = new Philosopher(0);
        p[1] = new Philosopher(1);
        p[2] = new Philosopher(2);
        p[3] = new Philosopher(3);
        p[4] = new Philosopher(4);

        for (int i = 0; i<5; i++) {
            try{
                p[i].run();

                if(i == 4) {
                   p.notifyAll();
                }
            }
            catch(IllegalMonitorStateException e) {}   
        }  
    } 
}

I'm creating 5 philosophers(threads). Each one of those has a wait() instruction in their code:

@Override
public void run() {
    int rand;

    if (status == 0) {
        System.out.println("Philosopher " + id + " is waiting.");
        try {
            wait();
            System.out.println("Awoken");
            while(status == 0) {
                    System.out.println("Philosopher " + id + " is thinking.");
                    sleep(100);
                    rand = ThreadLocalRandom.current().nextInt(0,100);                    
                    if(rand > 95){
                        status = 1;
                        System.out.println("Philosopher " + id + " changed state to hungry.");
                    }
                }
        }    
        catch(InterruptedException e) {
            System.out.println("Error!");
        }
        catch(IllegalMonitorStateException e) {}
    }
}

The problem is that when invoking notifyAll(), the processes don't awake and they just die after executing the run() method of each thread.

If anyone is wondering, I'm not using synchronized because I need to run the methods at the same time.

Also, I've tried to put notifyAll() inside the run() method of the threads.

Can anyone tell me what's going on and why are the threads not continuing with their code?


Solution

  • Problems

    1. notify[All]() and wait() should be used on the same instance. You are notifying on the array Philosopher[] p, but waiting on this which is a Philosopher. It's like I am waiting for you, but you are notifying Sarah that you're going to be late.

    2. You have created the threads but haven't started them properly. Calling run will execute the method in the current thread. Use the method start instead. It begins execution concurrently.

    3. To use x.notify[All]() or x.wait(), you have to be within a synchronised block synchronized(x) { ... }. Ignoring IllegalMonitorStateException won't help you at all.

    Answers

    ... why are the threads not continuing with their code?

    They might call wait after the 4th thread notifies them.

    ... the processes don't awake and they just die ...

    They don't die, they still wait until you terminate the program.

    I'm not using synchronizedbecause I need to run the methods at the same time

    You need to run the methods at the same time correctly, right? Here, synchronisation is required at least for building wait-notify communication.