在notifyAll()之后线程没有唤醒;

时间:2014-04-03 03:06:58

标签: java multithreading

好的,所以我有这些扩展Thread的类,我应该做的是:

  1. 让所有的列到达。
  2. 当列到达时,他们会说'嗨'。
  3. 如果老师到了但并非所有的Alumns都已到达,那么他应该等待()等待他们。
  4. 当教师全部在那里时,栏目应该通知()。
  5. alumn是一个用布尔值0初始化的Thread。

    教师是用布尔值1初始化的线程。

    人/问候代码

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

    主要课程

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

    问题: 如果老师先到达,他会去等待()...然后列到达,但他从不醒来。 如果老师没有先到达,他仍然没有醒来! 如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

  

如果老师先到达,他会去等待()...然后列到达   但他永远不会醒来。

所有人都会实例化自己的问候语,该问候语会在this上同步,因此也会在this上等待/通知。每个人都使用自己的信号量,这不是你想要的。您应该对所有实例同步对象(可能是Greeting.class)。

  

如果老师没有先到达,他仍然没有醒来!如何解决这个问题?

只需检查所有列是否存在。如果是问候,否则等待通知。然后再检查一下。检查必须是同步块的一部分,以避免竞争条件。

答案 1 :(得分:0)

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