java - java中如何让两架飞机同步降落在两条不同的跑道上?

标签 java synchronization

在我的空中交通管制应用程序中,我尝试将两架飞机降落在两条不同的跑道上。我已经同步了 2 条跑道,遗憾的是,当我添加大约 3-4 架飞机时,只有一架飞机着陆。

我应该得到的顺序是(我在同步一条跑道后得到这个):

alt text

同步两个跑道(跑道类的2个对象)后得到的订单:

alt text

[如果你看到第二张图并将其与第一张图进行比较,在第二张图中(错误的),只有一架飞机着陆,之后没有飞机着陆。 我非常希望解决这个问题,就像第一个图中所示]

<小时/>

控制.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();
}
}
<小时/>

飞行.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);






}
}
<小时/>

Runway.java

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

        }
    }
}
}
<小时/>

如何使用空中交通管制的说明

编译程序并单击添加航类按钮

alt text

对于航类号:输入整数,如 1、2 或 3。

对于机甲,医疗,燃料,天气状态放置OK(不使用放置失败)

对于土地状态,始终将其置于土地。

点击确定

alt text

<小时/>

我想要一个同步两条跑道的修复程序(我已经完成了同步代码,我希望有人查看它并告诉我下一步该做什么),以便在第一条跑道繁忙时飞机可以着陆。

感谢您的宝贵时间。如果这对你来说太过分了,我深表歉意。再次感谢。

最佳答案

这是很多代码,我无法详细介绍所有代码(我建议您从下次开始将代码简化并精简到最低限度。这样人们会更愿意提供帮助),但这里有我的观察:

您似乎多次使用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/

相关文章:

java - 使用 ConcurrentMap 双重检查锁定

javascript - Google Chrome 扩展程序的 storage.sync 上出现 QUOTA_BYTES_PER_ITEM 错误

Java回文程序无法运行

java - 当不涉及与 'then..' 方法链接时,是否保证 CompletableFuture 排序?

android - 渲染脚本 rs.finish()、allocation.syncAll()、copyTo() : wait till kernel execution finishes

iphone - PerformSelectorOnMainThread 抛出消息已释放

java - java.util.concurrent.ConcurrentHashMap.putIfAbsent 是否需要在同步块(synchronized block)中?

java - 获取某个正则表达式中字符串的值

java - 如何让几十个线程同时运行

java - 二维对象数组