2015-04-15 31 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你们!

相关问题