Java wait()或notifyAll()创建无限循环
我有一个模拟机场的程序,该程序基于以下代码: 它有三个类:Airport、Airport和AirportSimulator(在我的例子中),并使用线程来同步动作 我遇到的问题是,当飞机等待跑道空间着陆时,notifyAll()函数似乎不起作用,因此飞机处于“等待”空间的无限循环中 我认为问题在于wait()由于没有被中断而无限大,或者notifyAll()不工作并通知正在等待它们的线程(飞机) 感谢您的帮助 编辑:这里是课程 framework.javaJava wait()或notifyAll()创建无限循环,java,multithreading,Java,Multithreading,我有一个模拟机场的程序,该程序基于以下代码: 它有三个类:Airport、Airport和AirportSimulator(在我的例子中),并使用线程来同步动作 我遇到的问题是,当飞机等待跑道空间着陆时,notifyAll()函数似乎不起作用,因此飞机处于“等待”空间的无限循环中 我认为问题在于wait()由于没有被中断而无限大,或者notifyAll()不工作并通知正在等待它们的线程(飞机) 感谢您的帮助 编辑:这里是课程 framework.java public class Airplan
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。所有相关代码都已添加,很抱歉之前没有包含它。无法掌握代码块的窍门!