gpt4 book ai didi

java - wait() 或 notifyAll() 创建无限循环

转载 作者:太空宇宙 更新时间:2023-11-04 06:56:33 26 4
gpt4 key购买 nike

我有一个模拟机场的程序,该程序基于此处找到的代码:http://www.javapractices.com/topic/TopicAction.do?Id=51

其中包含三个类:Airport、Airplane 和 AirportSimulator(在我的例子中),并使用线程来同步操作。

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

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

感谢任何帮助。

编辑:这是类(class)。

飞机.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();
}
}
}
}
}

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

最佳答案

当我运行你的程序时,Airplane 线程不会挂起:它调用 takeOff()、fly() 和 land()。之后它终止...

...不打印任何消息。

每次我运行它时,在它调用land()的那一刻,跑道是可用的,所以它永远不会进入while()循环,它永远不会调用wait()。它就回来了,故事就结束了。

<小时/>

一些评论:

您的程序不会尝试阻止不止一架飞机同时使用“跑道”。我加了引号,因为你的模型中确实没有跑道。只有一个 boolean 标志,只要它为真,那么每架想要起飞或降落的飞机都被允许这样做。

你的程序 sort-of 处理 InterruptedException,而 sort-of 不处理。该语言强制您编写处理程序,并且在每个处理程序中,您都小心地重置中断标志,但随后没有任何东西会测试该标志。在大多数实际程序中,中断意味着“正常关闭”。在这种情况下,您需要在每个循环中测试 isInterrupted(),如果为真则进行清理并退出。

如果你不想惹这些麻烦,那么你也可以这样写:

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

关于java - wait() 或 notifyAll() 创建无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22667485/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com