2015-04-15 29 views
0

我不知道該怎麼做!我是初學者, ​​工作正常,但裏面的方法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(); 
    } 
} 

//這是Patient類

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

我相信你正試圖在不同的線程(Patient)上共享公共資源(Doctor),在這種情況下,你需要鎖定Doctor not Patient的普通對象。

試試這個。

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

您的代碼存在問題,有兩個線程,每個調用等待自己(this),在調用某個對象的等待後,其他線程需要調用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你們!

相關問題