在我的空中交通管制应用程序中,我试图将两架飞机降落在两条不同的跑道上。我已经完成了2条跑道的同步,可悲的是,当我添加大约3-4架飞机时,只有一架飞机降落。
我应该得到的命令是(我在同步一个跑道后得到了这个命令):
同步两个跑道(跑道类的2个对象)后得到的命令:
[如果您看到第二张图并将其与第一张图进行比较,则在第二张图(错误的一个图)中,只有一个飞机降落,之后没有一个飞机降落。我非常希望对此进行修复,如第一张图所示]
Control.java
import java.awt.Color;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JSeparator;
public class Control {
//JFrame
JFrame main = new JFrame();
//MenuBar
JMenuBar menuBar = new JMenuBar();
//Adding the menu
JMenu fileMenu = new JMenu("File");
JMenu functionMenu = new JMenu("Function");
JMenu helpMenu = new JMenu("Help");
//Adding the Menu Item
JMenuItem addFlight = new JMenuItem("Add Flight");
JMenuItem exit = new JMenuItem("Exit");
JMenuItem landFlight = new JMenuItem("Land Flight");
JMenuItem virtualPath = new JMenuItem("Virtual Path");
JMenuItem flightDetails = new JMenuItem("Flight Details");
JMenuItem about = new JMenuItem("About ...");
//JPanel
JPanel pnlButton = new JPanel();
//Buttons
JButton btnAddFlight = new JButton("Add Flight");
JButton btnLandFlight = new JButton("Land Flight");
JButton btnVirtualPath = new JButton("Virtual Path");
JButton btnFlightDetails = new JButton("Flight Details");
//Test Button
JButton btnArrayListContents = new JButton("ArrayList Contents");
public Control() {
//Adding to the file menu
fileMenu.add(addFlight);
fileMenu.add(exit);
//Adding to the function menu
functionMenu.add(landFlight);
functionMenu.add(virtualPath);
functionMenu.add(flightDetails);
//Adding to the help menu
helpMenu.add(about);
//Separators
exit.add(new JSeparator());
flightDetails.add(new JSeparator());
//Adding the Menus to the Menu Bar
menuBar.add(fileMenu);
menuBar.add(functionMenu);
menuBar.add(helpMenu);
//FlightInfo setbounds
btnAddFlight.setBounds(30, 30, 120, 30);
btnLandFlight.setBounds(30, 80, 120, 30);
btnVirtualPath.setBounds(30, 130, 120, 30);
btnFlightDetails.setBounds(30, 180, 120, 30);
btnArrayListContents.setBounds(30, 230, 200, 30);
//JPanel bounds
pnlButton.setLayout(null);
//Adding to JFrame
pnlButton.add(btnAddFlight);
pnlButton.add(btnLandFlight);
pnlButton.add(btnVirtualPath);
pnlButton.add(btnFlightDetails);
main.add(pnlButton);
// JFrame properties
main.setJMenuBar(menuBar);
main.setBackground(Color.red);
main.setSize(230, 300);
main.setTitle("Air Traffic Control");
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.setVisible(true);
//Adding the actionlistener
btnAddFlight.addActionListener(new AddFlight());
//btnLandFlight.addActionListener(new LandFlight());
//btnArrayListContents.addActionListener(new ArrayList());
}
public static void main(String[] args) {
new Control();
}
}
AddFlight.java
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class AddFlight implements ActionListener {
//String array
String[] status = {"Select", "Ok", "Failure"};
String[] landStatus = {"Select", "To Land", "Landing on Runway 1","Landing on Runway 2","Landed"};
//JPanel
JPanel pnlInput = new JPanel(new GridLayout(5, 3, 10, 10));
//Add textfields here
JTextField txtFlightNo = new JTextField(8);
JComboBox cmbStatus = new JComboBox(status);
JComboBox cmbLandStatus = new JComboBox(landStatus);
//Add labels here
JLabel lblFlightNo = new JLabel("Flight No : ");
JLabel lblStatus = new JLabel("Mechanical,Medical,Fuel,Weather Status : ");
JLabel lblLandStatus = new JLabel("Land Status : ");
//ArrayList
List<Flight> Flights = new ArrayList<Flight>();
//int flightNo = 0;
Flight newFlight;
public AddFlight() {
//Adding flightno to panel
pnlInput.add(lblFlightNo);
pnlInput.add(txtFlightNo);
//Adding mechanicalstatus to the panel
pnlInput.add(lblStatus);
pnlInput.add(cmbStatus);
//Adding landstatus to the panel
pnlInput.add(lblLandStatus);
pnlInput.add(cmbLandStatus);
}
public void actionPerformed(ActionEvent e) {
int result = JOptionPane.showConfirmDialog(null, pnlInput, "Flight Details",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
System.out.println("Plane [" + txtFlightNo.getText() + "] has arrived at the airport.\n");
//System.out.println("Mechanical status " + cmbMechanicalStatus.getSelectedItem() + "\n");
}
Flights.add(new Flight(txtFlightNo.getText(),
(String) cmbStatus.getSelectedItem(),
(String) cmbLandStatus.getSelectedItem(),0,0)); //Last two items are safety and runway respectively
//persons.add(new Flight("UL210", "FAILURE"));
// for (Flight AddFlight : Flights) {
// System.out.println("FLight No : " + AddFlight.getFlightNo());
// System.out.println("Status : " + AddFlight.getStatus());
//
//
// }
// ListIterator listIterator = Flights.listIterator();
// while(listIterator.hasNext())
// System.out.println(listIterator.next());
System.out.println("Array Size is : "+Flights.size());
for (int p=0; p<Flights.size();p++){
if(p==Flights.size()-1){
// int a = Integer.parseInt(Flights.get(p).getFlightNo());
// System.out.println(a);
//System.out.println(Flights.get(p).getSafety());
//Making Threads
makeThread(Flights, Flights.get(p));
System.out.println("One thread made");
}
}
//System.out.println();
//flightNo++;
}
public void makeThread(List<Flight> Flights, Flight newFlight){
Thread flight = new Thread(new Flight(Flights, newFlight));
flight.start();
}
}
Flight.java
import java.util.List;
public class Flight implements Runnable {
//Variables
String strFlightNo;
String strStatus;
String strLandStatus;
int safety;
int runway;
//Reference Variables
Flight newFlight;
FlightLand fLand = new FlightLand();
//ArrayList
List<Flight> Flights;
Runway runOne = new Runway();
Runway runTwo = new Runway();
public Flight(List<Flight> Flights,Flight newFlight) {
this.newFlight = newFlight;
this.Flights = Flights;
}
public Flight(String strFlightNo, String strStatus, String strLandStatus, int safety, int runway) {
this.strFlightNo = strFlightNo;
this.strStatus = strStatus;
this.strLandStatus = strLandStatus;
this.safety = safety;
this.runway = runway; // no runway =0, runway1=0,runway2=2;
}
//Getters
public String getFlightNo() {
return strFlightNo;
}
public String getStatus() {
return strStatus;
}
public String getLandStatus() {
return strLandStatus;
}
public int getSafety() {
return safety;
}
public int getRunway() {
return runway;
}
//Setters
public void setFlightNo(String strFlightNo) {
this.strFlightNo = strFlightNo;
}
public void setStatus(String strStatus) {
this.strStatus = strStatus;
}
public void setLandStatus(String strLandStatus) {
this.strLandStatus = strLandStatus;
}
public void setSafety(int safety) {
this.safety = safety;
}
public void setRunway(int runway) {
this.runway = runway; // no runway =0, runway1=0,runway2=2;
}
public void run() {
try{
while(!fLand.flightLandCheck(newFlight))
runOne.flight01Enter(Flights, newFlight);
runTwo.flight02Enter(Flights, newFlight);
while(fLand.flightLandCheck(newFlight))
runOne.flight01Exit(Flights, newFlight);
runTwo.flight02Exit(Flights, newFlight);
}catch(InterruptedException e){}
}
}
FlightLand.java
import java.util.List;
public class FlightLand {
int x = 0;
Flight newFlight;
public FlightLand() {
}
public synchronized boolean flightLandCheck(Flight newFlight) throws InterruptedException {
if (newFlight.getLandStatus().equals("To Land") && x == 0) {
System.out.println("Flight " + newFlight.getFlightNo() + " is about to Land");
x++;
Thread.sleep(100);
return false;
} else if (newFlight.getLandStatus().equals("To Land") && x == 1) {
x++;
Thread.sleep(100);
return true;
} else if (newFlight.getLandStatus().equals("To Land") && x == 2) {
//System.out.println("Flight " + newFlight.getFlightNo() + " is Landing");
if (newFlight.getRunway() == 31) {
newFlight.setLandStatus("Landing on Runway 1");
System.out.println("Flight " + newFlight.getFlightNo() + " is " + newFlight.getLandStatus());
Thread.sleep(5000);
x -= 2;
newFlight.setLandStatus("Landed");
Thread.sleep(100);
System.out.println("Flight " + newFlight.getFlightNo() + " has " + newFlight.getLandStatus());
} else if (newFlight.getRunway() == 32) {
newFlight.setLandStatus("Landing on Runway 2");
System.out.println("Flight " + newFlight.getFlightNo() + " is " + newFlight.getLandStatus());
Thread.sleep(5000);
x -= 2;
newFlight.setLandStatus("Landed");
Thread.sleep(100);
System.out.println("Flight " + newFlight.getFlightNo() + " has " + newFlight.getLandStatus());
}
return true;}
else {
return false;
}
//newFlight.setRunway(1);
}
}
跑道
import java.util.List;
public class Runway {
//Reference variables
Flight newFlight;
int runOneBlock = 0;
List<Flight> Flights;
int i;
public Runway() {
}
synchronized void flight01Enter(List<Flight> Flights, Flight newFlight) throws InterruptedException {
for (int p = 0; p < Flights.size(); p++) {
if (Flights.get(p).getRunway() == 2) {
//System.out.println("Plane" +Flights.get(p).getFlightNo()+ "is waiting");
wait();
// int a = Integer.parseInt(Flights.get(p).getFlightNo());
// System.out.println(a);
//System.out.println(Flights.get(p).getSafety());
//Making Threads
}
}
newFlight.setRunway(1);
}
synchronized void flight01Exit(List<Flight> Flights, Flight newFlight) {
newFlight.setRunway(31);
//System.out.println("Output of i shud be zero (check)" + i);
for (int p = 0; p < Flights.size(); p++) {
if (Flights.get(p).getRunway() == 0) {
//System.out.println("Plane" +Flights.get(p).getFlightNo()+ "is waiting");
notifyAll();
// int a = Integer.parseInt(Flights.get(p).getFlightNo());
// System.out.println(a);
//System.out.println(Flights.get(p).getSafety());
//Making Threads
}
}
}
synchronized void flight02Enter(List<Flight> Flights, Flight newFlight) throws InterruptedException {
for (int p = 0; p < Flights.size(); p++) {
if (Flights.get(p).getRunway() == 1) {
//System.out.println("Plane" +Flights.get(p).getFlightNo()+ "is waiting");
wait();
// int a = Integer.parseInt(Flights.get(p).getFlightNo());
// System.out.println(a);
//System.out.println(Flights.get(p).getSafety());
//Making Threads
}
}
newFlight.setRunway(2);
}
synchronized void flight02Exit(List<Flight> Flights, Flight newFlight) {
newFlight.setRunway(32);
//System.out.println("Output of i shud be zero (check)" + i);
for (int p = 0; p < Flights.size(); p++) {
if (Flights.get(p).getRunway() == 0) {
//System.out.println("Plane" +Flights.get(p).getFlightNo()+ "is waiting");
notifyAll();
// int a = Integer.parseInt(Flights.get(p).getFlightNo());
// System.out.println(a);
//System.out.println(Flights.get(p).getSafety());
//Making Threads
}
}
}
}
有关如何使用空中交通管制的说明
编译程序,然后单击添加Flight按钮
对于航班号:输入整数,例如1或2或3。
对于机甲,医疗,燃料,天气状况为“正常”(不使用推杆失败)
对于“土地”状态,请始终放置“土地”。
点击确定
我想要一个同步两个跑道的解决方法(我已经完成了同步代码,我希望有人看一下并告诉我下一步该怎么做),以便在一个跑道繁忙时飞机可以降落。
感谢您的时间。如果这对您来说太多了,对不起。再次感谢。
最佳答案
这是很多代码,我无法一一列举(我建议您从下一次开始简化代码,并将其剥离到最低限度。这样,人们会更乐于提供帮助),但这是我的观察结果:
您似乎多次使用synchronized
,并且至少使用一次wait()
。这似乎是不合理的。特别是,如果您wait()
,某处一定有notifyAll()
(或notify()
),但我看不到,所以这似乎肯定是错误的(也许这就是您的飞机停止着陆的原因)。
现在,有一个简单的建议可以使其工作(某种伪代码):
class Main {
private final Runway[] runways = { new Runway(), new Runway() };
void main(){
for(int i=0; i<5; i++){
System.out.println("Plane #" + i + " attempting to land.");
Runway runway = runways.get(i%runways.length);
runway.land(new Plane(i));
}
}
}
class Runway {
public synchronized land(Plane plane){
System.out.println(plane + " landed.");
}
}
仅此一项就足以同步着陆。只需在每条跑道上同步,您的飞机就会等到其前面的飞机完成降落。当您的飞机必须等待满足某些条件时,使用
wait()
。这是一个例子:class Main {
private final Runway[] runways = { new Runway(), new Runway() };
void main(){
Thread maintainer = new Thread(){
public void run(){
try{
Thread.sleep(500);
for(Runway runway : runways){
runway.ready = true;
runway.notifyAll();
}
}catch(InterruptedException e){}
};
maintainer.start();
for(int i=0; i<5; i++){
System.out.println("Plane #" + i + " attempting to land.");
Runway runway = runways.get(i%runways.length);
runway.land(new Plane(i));
}
}
}
class Runway {
boolean ready; //getter/setter omitted..
public synchronized land(Plane plane){
//You always have to wait like this, never `if (something) wait();`
while(!ready){
wait();
}
//We have the lock and runway is ready
System.out.println(plane + " landed.");
ready = false; //runway is littered?
}
}
关于java - 如何在Java中使两个飞机降落在两个不同的同步跑道中?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3233368/