我有一个模拟机场的程序,该程序基于此处的代码:http://www.javapractices.com/topic/TopicAction.do?Id=51
其中有三个类:Airport,Airplane和AirportSimulator(在我的情况下)并使用线程来同步动作。
我遇到的问题是,当飞机正在等待跑道空间着陆时,notifyAll()功能似乎不起作用,因此飞机停留在“等待”的无限循环中空间。
我认为问题在于wait()由于没有被中断而无限,或者notifyAll()没有工作,并通知正在等待它们的线程(飞机)。 / p>
感谢任何帮助。
编辑:这是课程。
Airplane.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");
}
}
答案 0 :(得分:1)
当我运行程序时,Airplane线程不会挂起:它调用takeOff(),fly()和land()。之后它终止......
...没有打印任何消息。
每次我运行它时,在它调用land()的确切时刻,跑道都可用,因此它永远不会进入while()循环,它从不调用wait()。它只是回归,这就是故事的结束。
几点意见:
您的程序不会试图让多架飞机同时使用“跑道”。我加入了恐慌报价,因为你的模型中确实没有跑道。只有一个布尔标志,只要它是真的,那么每架想要起飞或降落的飞机都可以这样做。
您的程序排序处理InterruptedException,而排序则不处理。语言强迫你编写处理程序,并且在每个处理程序中,你仔细地重置了被中断的标志,但之后没有任何东西测试过标志。在大多数实际程序中,中断意味着“优雅地关闭”。在这种情况下,您希望在每个循环中测试isInterrupted(),并清理并退出,如果它是真的。
如果你不想解决所有麻烦,那么你也可以写下:
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}