Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java wait()或notifyAll()创建无限循环_Java_Multithreading - Fatal编程技术网

Java wait()或notifyAll()创建无限循环

Java wait()或notifyAll()创建无限循环,java,multithreading,Java,Multithreading,我有一个模拟机场的程序,该程序基于以下代码: 它有三个类:Airport、Airport和AirportSimulator(在我的例子中),并使用线程来同步动作 我遇到的问题是,当飞机等待跑道空间着陆时,notifyAll()函数似乎不起作用,因此飞机处于“等待”空间的无限循环中 我认为问题在于wait()由于没有被中断而无限大,或者notifyAll()不工作并通知正在等待它们的线程(飞机) 感谢您的帮助 编辑:这里是课程 framework.java public class Airplan

我有一个模拟机场的程序,该程序基于以下代码:

它有三个类:Airport、Airport和AirportSimulator(在我的例子中),并使用线程来同步动作

我遇到的问题是,当飞机等待跑道空间着陆时,notifyAll()函数似乎不起作用,因此飞机处于“等待”空间的无限循环中

我认为问题在于wait()由于没有被中断而无限大,或者notifyAll()不工作并通知正在等待它们的线程(飞机)

感谢您的帮助

编辑:这里是课程

framework.java

public class Airplane implements Runnable
{
    public Airplane(Airport anAirport, String FlightID)
    {
        fAirport = anAirport;
        aFlightID = FlightID;
    }

    @Override
    public void run()
    {
        takeOff();
        fly();
        land();
    }

    //Private
    private Airport fAirport;
    private String aFlightID;

    private void takeOff()
    {
        synchronized(fAirport)
        {
            while(!fAirport.hasAvailableRunway())
            {
                System.out.println(aFlightID + ": waiting for runway space");
                try
                {
                    fAirport.wait();
                }
                catch(InterruptedException ex)
                {
                    System.err.println(ex);
                    Thread.currentThread().interrupt();
                }
            }
            System.out.println(aFlightID + ": departing now...");
        }
    }

    private void fly()
    {
        System.out.println(aFlightID + ": now flying...");
        try
        {
            //wait for 10 seconds
            Thread.sleep(10000);
        }
        catch(InterruptedException ex)
        {
            System.err.println(ex);
            Thread.currentThread().interrupt();
        }
    }

    private void land()
    {
        synchronized(fAirport)
        {
            while(!fAirport.hasAvailableRunway())
            {
                System.out.println(aFlightID + ": waiting for runway space");
                try
                {
                    fAirport.wait();
                }
                catch(InterruptedException ex)
                {
                    System.err.println(ex);
                    Thread.currentThread().interrupt();
                }
            }
        }
    }
}
Airport.java

public class Airport implements Runnable
{

    public Airport(String aName)
    {
        super();
        fName = aName;
    }

    public synchronized boolean hasAvailableRunway()
    {
        return fHasAvailableRunway;
    }

    @Override
    public void run()
    {
        System.out.println("Running: " + fName + " Airport.");
        while(true)
        {
            try
            {
                synchronized(this)
                {
                    //Toggle runway state between available and unavailable
                    fHasAvailableRunway = !fHasAvailableRunway;
                    System.out.println(fName + " Has Available Runway: " + fHasAvailableRunway);
                    //Notify waiters of the state change
                    this.notifyAll();
                }
                Thread.sleep(2000); //Pause for a couple of seconds
            }
            catch(InterruptedException ex)
            {
                System.err.println(ex);
                Thread.currentThread().interrupt();
            }
        }
    }

    //Private
    private boolean fHasAvailableRunway = true;
    private String fName;

}
最后是AirportSimulator.java

public class AirportSimulator 
{
    public static void main(String[] args)
    {
        System.out.println("Running Airport Simulation");

        //Create an airport and start running
        Airport leedsBradfordAirport = new Airport("Leeds & Bradford International");
        Thread airport = new Thread(leedsBradfordAirport);
        airport.start();

        //Create a plane and start running
        Thread airplaneOne = new Thread(new Airplane(leedsBradfordAirport, "Flight 2112"));
        //Thread airForceTwo = new Thread(new Airplane(leedsBradfordAirport, "Flight 1986"));
        airplaneOne.start();
        //airForceTwo.start();

        System.out.println("Terminating original thread");
    }
}

当我运行程序时,飞机线程不会挂起:它调用takeOff()、fly()和land()。在那之后它终止了

…不打印任何消息

每次我运行它时,在它调用land()的确切时刻,跑道是可用的,因此它从不进入while()循环,也从不调用wait()。它刚刚回来,故事就到此结束


几点意见:

您的程序不会试图阻止多架飞机同时使用“跑道”。我加上了吓人的语录,因为你的模型里真的没有跑道。只要有一个布尔标志,只要它是真的,那么每架想要起飞或降落的飞机都可以这样做

您的程序可以处理InterruptedException,也可以不处理。这种语言迫使您编写处理程序,在每个处理程序中,您都会小心地重置中断标志,但是没有任何东西会测试该标志。在大多数实际程序中,中断意味着“优雅地关闭”。在这种情况下,您需要在每个循环中测试isInterrupted(),如果是真的,则清除并退出

如果你不想惹那么多麻烦,那么你不妨写:

} catch (InterruptedException ex) {
    throw new RuntimeException(ex);
}

在不查看代码的情况下,关于notify和notifyAll需要了解的一件事是,它只会唤醒等待的线程。如果没有线程在等待,那么notifyAll将是一个no-op。所有相关代码都已添加,很抱歉之前没有包含它。无法掌握代码块的窍门!