使用Java监视器的简单程序

使用Java监视器的简单程序,java,concurrency,monitors,Java,Concurrency,Monitors,我有一个简单的Java程序,它利用监视器让客户进入登机区。我想我把wait()和notify()语句放在了错误的位置,导致了程序死锁,但是,我自己无法解决这个问题。下面是我写的代码 public class AdultCouple extends Thread { private boolean onRide = false; private int ID; AdultCouple(int ID) { this.ID = ID; }

我有一个简单的Java程序,它利用监视器让客户进入登机区。我想我把wait()和notify()语句放在了错误的位置,导致了程序死锁,但是,我自己无法解决这个问题。下面是我写的代码

public class AdultCouple extends Thread
{
    private boolean onRide = false;
    private int ID;

    AdultCouple(int ID)
    {
        this.ID = ID;
    }

    public synchronized void getIn()
    {
        while (!Main.isDoorOpen)
        {
            try
            {
                wait();
            }
            catch (InterruptedException ex)
            {

            }
            System.out.println("Go through");
        }
        System.out.println("Couple " + ID + " get in boarding area.");
        onRide = true;
        Main.peopleInBoardingArea++;
        notify();
    }

    public void run() 
    {
        getIn();
    }
}


public class Area extends Thread
{

    Area()
    {
    }

    public synchronized void openDoor()
    {
        while (Main.peopleInBoardingArea != 0)
        {
            try
            {
                wait();
            }
            catch (InterruptedException ex)
            {
            }
        }
        System.out.println("Area opens");
        Main.isDoorOpen = true;
        notifyAll();
    }

    public synchronized void closeDoor()
    {
    }


    public void run() 
    {
        openDoor();
    }
}


public class ParentKid extends Thread
{

    private boolean onRide = false;
    private int ID;

    ParentKid(int ID)
    {
        this.ID = ID;
    }

    public synchronized void getIn()
    {
        while (!Main.isDoorOpen)
        {
            try
            {
                wait();
            }
            catch (InterruptedException ex)
            {

            }
            System.out.println("Go through");
        }
        System.out.println("Couple " + ID + " get in boarding area.");
        onRide = true;
        Main.peopleInBoardingArea++;
        notify();
    }

    public void run() 
    {
        getIn();
    }

}

public class Main 
{

    public static boolean isDoorOpen = false;
    public static int peopleInBoardingArea = 0;

    public static void main(String args[])
    {
        Thread t3 = new Area();
        Thread t1 = new ParentKid(1);
        Thread t2 = new AdultCouple(2);


        t1.start();
        t2.start();
        t3.start();

        try
        {
            t1.join();
            t2.join();
            t3.join();
        }
        catch (InterruptedException ex)
        {

        }
    }
}

问题是您在不同的对象上同步。当你写这样的东西的时候

public synchronized foo() {...}
您可以在此对象上同步。在您的情况下,您在当前线程上同步,这没有任何意义。您应该在同一对象上同步

public class Main {

    public static Object lock = new Object();
    ...
}

public class AdultCouple extends Thread
{
    private boolean onRide = false;
    private int ID;

    AdultCouple(int ID)
    {
        this.ID = ID;
    }

    public void getIn()
    {
        synchronized (Main.lock) {
            while (!Main.isDoorOpen) {
                try {
                    Main.lock.wait();
                } catch (InterruptedException ex) {

                }
                System.out.println("Go through");
            }
            System.out.println("Couple " + ID + " get in boarding area.");
            onRide = true;
            Main.peopleInBoardingArea++;
            Main.lock.notifyAll();
        }
    }

    public void run()
    {
        getIn();
    }
}

public class Area extends Thread
{

    Area()
    {
    }

    public void openDoor()
    {
        synchronized (Main.lock) {
            while (Main.peopleInBoardingArea != 0) {
                try {
                    Main.lock.wait();
                } catch (InterruptedException ex) {
                }
            }
            System.out.println("Area opens");
            Main.isDoorOpen = true;
            Main.lock.notifyAll();
        }
    }

    public synchronized void closeDoor()
    {
    }


    public void run()
    {
        openDoor();
    }
}

public class ParentKid extends Thread
{

    private boolean onRide = false;
    private int ID;

    ParentKid(int ID)
    {
        this.ID = ID;
    }

    public void getIn()
    {
        synchronized (Main.lock) {
            while (!Main.isDoorOpen) {
                try {
                    Main.lock.wait();
                } catch (InterruptedException ex) {

                }
                System.out.println("Go through");
            }
            System.out.println("Kid " + ID + " get in boarding area.");
            onRide = true;
            Main.peopleInBoardingArea++;
            Main.lock.notifyAll();
        }
   }


    public void run()
    {
        getIn();
    }

}

也不要使用notify()而是notifyAll()。我看不出有任何理由使用它

问题是您在不同的对象上同步。当你写这样的东西的时候

public synchronized foo() {...}
您可以在此对象上同步。在您的情况下,您在当前线程上同步,这没有任何意义。您应该在同一对象上同步

public class Main {

    public static Object lock = new Object();
    ...
}

public class AdultCouple extends Thread
{
    private boolean onRide = false;
    private int ID;

    AdultCouple(int ID)
    {
        this.ID = ID;
    }

    public void getIn()
    {
        synchronized (Main.lock) {
            while (!Main.isDoorOpen) {
                try {
                    Main.lock.wait();
                } catch (InterruptedException ex) {

                }
                System.out.println("Go through");
            }
            System.out.println("Couple " + ID + " get in boarding area.");
            onRide = true;
            Main.peopleInBoardingArea++;
            Main.lock.notifyAll();
        }
    }

    public void run()
    {
        getIn();
    }
}

public class Area extends Thread
{

    Area()
    {
    }

    public void openDoor()
    {
        synchronized (Main.lock) {
            while (Main.peopleInBoardingArea != 0) {
                try {
                    Main.lock.wait();
                } catch (InterruptedException ex) {
                }
            }
            System.out.println("Area opens");
            Main.isDoorOpen = true;
            Main.lock.notifyAll();
        }
    }

    public synchronized void closeDoor()
    {
    }


    public void run()
    {
        openDoor();
    }
}

public class ParentKid extends Thread
{

    private boolean onRide = false;
    private int ID;

    ParentKid(int ID)
    {
        this.ID = ID;
    }

    public void getIn()
    {
        synchronized (Main.lock) {
            while (!Main.isDoorOpen) {
                try {
                    Main.lock.wait();
                } catch (InterruptedException ex) {

                }
                System.out.println("Go through");
            }
            System.out.println("Kid " + ID + " get in boarding area.");
            onRide = true;
            Main.peopleInBoardingArea++;
            Main.lock.notifyAll();
        }
   }


    public void run()
    {
        getIn();
    }

}

也不要使用notify()而是notifyAll()。我看不出有任何理由使用它

一个问题是,您正在使用对类
Main
的静态字段的非同步访问。即使将它们更改为
volatile
也不适用于
++
运算符。一个问题是,您正在使用对类
Main
静态字段的非同步访问。即使将它们更改为
volatile
也不适用于
++
运算符。