2015-04-15 2 views
0

Я не знаю, что делать! Я новичок, public void checkUp(){} работал нормально, но внутри метод notifyAll() не будет уведомлять об wait().почему wait() не работает после вызова notifyAll()

public class Doctor extends Thread { 
    public static void main(String[] args) { 
     Doctor doctor = new Doctor(); 
     Patient patient1 = new Patient(doctor); 
     Patient patient2 = new Patient(doctor); 
     patient1.setName("Patient One"); 
     patient2.setName("Patient Two"); 
     patient1.start(); 
     patient2.start(); 
    } 
} 

// Это класс пациента

class Patient extends Thread { 
    Doctor d; 
    static boolean isAlready = false; 

    public Patient(Doctor d) { 
     this.d = d; 
    } 

    public void run() { 
     synchronized(this) { 
      if (isAlready == false) { 
       isAlready = true; 
       try { 
        System.out.println(Thread.currentThread().getName() + " Wait to see Doctor\n"); 
        wait(); 
        checkup(); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 

      } 
      checkup(); 
     } 

    } 

    public void checkup() { 
     synchronized(this) { 
      try { 
       System.out.println(Thread.currentThread().getName() + " Enter Doctor's Room!\n"); 
       System.out.println("After Consulting Doctor! '" + Thread.currentThread().getName() + "' Paid fees to Doctor\n"); 
       Thread.sleep(1000); 
       System.out.println(Thread.currentThread().getName() + " Notify to next Patient to enter Doctor's Room!\n"); 
       notifyAll(); 
       System.out.println(Thread.currentThread().getName() + " Leaves Hospital\n"); 

      } catch (Exception e) { 

      } 

      isAlready = false; 
     } 

    } 
} 
+0

привет, приветствую, вы должны попытаться дать как можно больше информации, как возможно – epoch

+1

Когда вызывается метод 'checkup' (кроме метода' run')? – ortis

+1

Все ваши пациенты ждут, пока другой пациент не назовет «notifyAll» ... Таким образом, никто из пациентов не звонит notifyAll, никогда (потому что все пациенты ждут) ... XD – inigoD

ответ

0

У вас есть два объекта пациента, и каждый из них только wait() s или notifyAll() себя s. Если объект «Пациент» входит в вызов wait(), кто собирается его уведомить?


Вы пытаетесь смоделировать очереди: Существует один врач, и есть много пациентов, которые каждый должен ждать своей очереди, чтобы обратиться к врачу.

Связав нить с каждым пациентом и заблокировав поток каждого пациента до момента его появления, вы используете скрытые очереди, используемые операционной системой для реализации синхронизации потоков.

Почему бы не использовать явную очередь вместо этого? Почему бы не представлять пациентов объектами в очереди и моделировать врача нитью, которая поочередно выбирает объекты пациента из очереди и обслуживает их?

1

Я считаю, что вы пытаетесь использовать общий ресурс (Doctor) для разных потоков (пациент). В этом случае вам нужно получить блокировку на общем объекте, который не является пациентом.

Попробуйте это.

class Patient extends Thread { 
    Doctor d; 
    public Patient(Doctor d) { 
     this.d = d; 
    } 
    public void run() { 
     synchronized (d) { 
      checkup(); 
     } 
    } 
    public void checkup() { 
     System.out.println(Thread.currentThread().getName() 
       + " Enter Doctor's Room!\n"); 
     System.out.println("After Consulting Doctor! '" 
       + Thread.currentThread().getName() + "' Paid fees to Doctor\n"); 
     Thread.sleep(1000); 
     System.out.println(Thread.currentThread().getName() 
       + " Notify to next Patient to enter Doctor's Room!\n"); 
     System.out.println(Thread.currentThread().getName() 
       + " Leaves Hospital\n"); 
    } 
} 
+0

спасибо pradeep !! но я просто узнаю о выжидании и уведомлении! так что только я написал программу! но это нормально работает – Elanthirian

+0

Проблема с вашим кодом, есть два потока, и каждый вызов ждет сам по себе (после этого), после вызова wait на определенном объекте другой поток должен вызывать notify/notifyAll на том же объекте, чтобы пробудить ожидающий поток. –

0
public class Patient extends Thread{ 
Doctor d; 
    static boolean isAlready = false; 

    public Patient(Doctor d) { 
     this.d = d; 
    } 

    public static void main(String[] args) { 
     Doctor doctor = new Doctor(); 
     doctor.start(); 
} 
    public void run() { 
     synchronized (d) { 
     // System.out.println(Thread.currentThread().getName()+" Runn\n"); 
      if (isAlready == false) { 
       try { 
        System.out.println(Thread.currentThread().getName()+ " Wait to see Doctor\n\n"); 
        isAlready = true; 
        d.wait(); 
        Thread.sleep(2000); 
        checkup(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 

      }else{ 
       checkup(); 
      } 
     } 

    } 
    public void checkup() { 
     synchronized (d) { 
      try { 
       System.out.println(Thread.currentThread().getName()+ " Enter Doctor's Room!\n"); 
       System.out.println("After Consulting Doctor! '"+ Thread.currentThread().getName()+ "' Paid fees to Doctor\n"); 
       Thread.sleep(1000); 
       System.out.println(Thread.currentThread().getName()+ " Notify to next Patient to enter Doctor's Room!\n"); 
       d.notify(); 
       isAlready = false; 
       System.out.println(Thread.currentThread().getName()+ " Leaves Hospital\n"); 

      } catch (Exception e) { 

      } 

      } 
    } 

} 


class Doctor extends Thread { 
    public void run(){ 

     String patientName[] ={"Aravi","Elaa","Sethu","Bala","Ram","Sharukazen","Sathish","Gold"}; 
     Patient[] patients=new Patient[patientName.length]; 
     Doctor doctor = new Doctor(); 
     for (int i =0; i<patientName.length;i++){ 
     patients[i] = new Patient(doctor); 
     patients[i].setName(patientName[i]); 
     patients[i].start(); 
     } 

} 

}

наконец я нашел Answer.thank вас, ребята!

Смежные вопросы