为什么在调用notifyAll()之后wait()不起作用

时间:2015-04-15 14:06:15

标签: java multithreading tags wait notify

我不知道应该做什么!我是初学者, public void checkUp(){}工作正常,但方法notifyAll()内部不会通知wait()

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

    }
}

4 个答案:

答案 0 :(得分:1)

我相信你正试图在不同的线程(病人)之间共享公共资源(医生),在这种情况下,你需要锁定医生而非病人的共同对象。

试试这个。

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

答案 1 :(得分:0)

您有两个Patient对象,每个对象只有wait()个或notifyAll()个。如果Patient对象进入wait()呼叫,谁将要通知它?


你正在试图建立一个队列:有一位医生,有很多病人必须等着轮到他们去看医生。

通过将线程与每个患者相关联,并通过阻止每个患者线程直到轮到它,您正在利用操作系统用来实现线程同步的隐藏队列。

为什么不使用显式队列呢?为什么不通过队列中的对象来代表患者,并通过从队列中逐个挑选患者对象并为其服务的线程对医生进行建模?

答案 2 :(得分: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();
        }

}

}

最后我找到了答案。谢谢你们!

答案 3 :(得分:0)

两个线程都将调用wait(),并在那里永远等待,直到调用checkup()。由于两个线程都在等待,因此任何一个都无法继续checkup()并从其中调用notifyAll()