简体   繁体   中英

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?

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.

要等到所有线程都到达某个点,请考虑使用CyclicBarrier

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM