David Merinos
David Merinos

Reputation: 1295

Thread not waking up after notifyAll();

OK, So I have these classes that extend Thread, what I'm supposed to do is:

  1. Let all alumns arrive.
  2. When alumns arrive they say 'Hi'.
  3. If the teacher arrives but not all of the Alumns have arrived then he should wait() for them.
  4. Alumns should notify() the teacher when they're all there.

An alumn is a Thread initialized with boolean value 0.

A teacher is a Thread initialized with boolean value 1.

Person/Greeting Code

    public class Person extends Thread {
    private Thread t;
    private String threadName;
    boolean id;
    Greeting greeting;
    public Person(String name,boolean tipo,int n){
        this.threadName = name;
        this.id=tipo;  
        greeting =new Greeting();
    }

    @Override
    public void run() {
        if(id==false) { 
            try {
                greeting.alumn(threadName);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
        else{
            try {
                greeting.teacher(threadName);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
        }
    public void start() 
  {
    System.out.println("Starting "+ threadName);
    if(t==null)
    {
      t=new Thread(this,threadName);
      t.start();
    }
  }
}

class Greeting {

    public void alumn(String s) throws InterruptedException{
        System.out.println(s);
       synchronized (this){
            System.out.println("Alumn: "+s);
            notifyAll();       
    }
    }

    public synchronized void teacher(String s) throws InterruptedException {
        wait();
        System.out.println(s);
    }
}

Main class

public class ClassRoom {
    public static void main(String [] args) {

        Person francisco = new Person("Francisco",false,1);
        Person jesus = new Person("Jesus", false,2);
        Person alberto = new Person("Alberto",false,3);
        Person karla = new Person("Karla",false,4);
        Person maestro = new Person("Professor",true,0);
        francisco.start();
        jesus.start();
        alberto.start();
        karla.start();
        maestro.start();
    }
}

The problem: If the teacher arrives first he goes to wait()...then alumns arrive but he never wakes up. If the teacher doesn't arrive first, he still never wakes up! How to fix this?

Upvotes: 2

Views: 983

Answers (2)

Alexey Malev
Alexey Malev

Reputation: 6531

To wait until all threads has arrived to certain point, consider using CyclicBarrier.

Upvotes: 0

Drunix
Drunix

Reputation: 3343

If the teacher arrives first he goes to wait()...then alumns arrive but he never wakes up.

All you Persons instantiate their own Greeting, which synchronzizes on this and therefore also waits/notifies on this. Each Person uses its own semaphore, which is not what you want. You should synchronize on the same object (perhaps Greeting.class) for all instances.

If the teacher doesn't arrive first, he still never wakes up! How to fix this?

Simply check if all alumns are there. If yes greet, else wait for notify. Afterwards check again. The check has to be part of the synchronized block to avoid race conditions.

Upvotes: 2

Related Questions