views:

123

answers:

1

In my Air traffic Control application, I am trying to land two planes in two different runways. I have done synchronizing of 2 runways, sadly only one plane lands when I added about 3-4 planes.

The order I should get is(I got this after synchronizing one runway):

alt text

Order I got after synchronizing two runways(2 objects of the runway class):

alt text

[If you see the second Diagram and compare it with the first, in the second diagram(wrong one), only one plane lands, after that none of the planes land. I would very much like a fix for that, like in the first diagram]


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);






}
}

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

        }
    }
}
}

Instructions on how to use the Air Tracffic Control

Compile the program and Click the add Flight button

alt text

For the Flight No: put whole numbers like 1 or 2 or 3.

For the Mech, medical,fuel, weather status put Ok (No use of putting failure)

For the Land status always put To Land.

Click ok

alt text


I would like a fix for synchronizing two runways(I have done the code for the synchronizing, I would like someone to look at it and tell me what to do next) so that planes can land if runway one is busy.

Thank you for your time. If this is too much for you I apologize. Thanks once again.

+1  A: 

This is a lot of code and I can't go over all of it (I suggest you simplify and strip the code to the bare minimum from next time. That way people will be more willing to help), but here are my observations:

You seem to be using synchronized several times and wait() at least once. This seems unreasonable. Especially, if you wait(), there got to be notifyAll() (or notify()) somewhere, and I don't see this so this seems certainly wrong (perhaps that's why your planes cease to land).

Now, here is a simple suggestion to make it work (kind of pseudo code):

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

This alone is sufficient to synchronize landing. Just by synchronizing on each runway, your planes will wait until the one ahead of it has finished landing. wait() is used when your planes have to wait for certain conditions to be met. Here is an example:

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?
    }
}
Enno Shioji