2

I want to make a plane (Thread) fly from one airfield to another. When a plane is starting the airfield is blocked for 5 sec. (if another plane wants to land or take off - must wait). If a plane reach its destination it lands (if airfield is not blocked by another plane) and then takes a random airfield and fly there and so on.... I have questions in comments - how to make a thread wait ? And what else is wrong with my code ? Here is my class Samolot aka Plane:

     public class Samolot extends Thread{ 

        int id;
        double paliwo;
        Lotnisko source; //Lotnisko aka airfield
        Lotnisko dest;
      double xPosition;
      double yPosition;
        double xTarget;
      double yTarget;

    public Samolot(Lotnisko source, Lotnisko dest) {


        this.source = source;
        this.dest = dest;
        paliwo = 100;

    }
public void run(){
         while(true){

            tryStart();


         }
     }


     public void tryStart(){
         if(source.pas == true){  // if true the airfield is not blocked and we can go
            source.timer();      // its a method in class Lotnisko, makes pas = false for 8sec 
            lecimy(source, dest);
         }
         else if(source.pas == false){
             // how to make a thread wait ? 
         }
     }

public void tryLadowanie(){
         if(dest.pas == true){
             dest.timer();

            source = dest;
            dest = Rand(source);
            tryStart();
        } 
         else if(dest.pas == false){
             //how to make a thread wait ?
         }



     }
     public void lecimy(Lotnisko source, Lotnisko dest){

        xPosition = source.coords.getX();
        yPosition = source.coords.getY();
        xTarget = dest.coords.getX();
        yTarget = dest.coords.getY();


        while( (xPosition != xTarget) && (yPosition != yTarget) ){
            update();

            try{

                sleep(100);// ok 
                }
            catch (InterruptedException e) {
                System.out.println("Error");
                                    }
     }
     tryLadowanie();
     }



    public void update() {

        paliwo -= 0.05;
        double dx = xTarget - xPosition;
        double dy = yTarget - yPosition;
        double length = sqrt(dx*dx+dy*dy);

        dx /= length;
        dy /= length;

        if (Math.abs(dest.coords.getX() - source.coords.getX()) < 1)
            dx = 0;
        if (Math.abs(dest.coords.getY() - source.coords.getY()) < 1)
            dy = 0;
            xPosition += dx;
            yPosition += dy;
  }

    public Point getPositions() {
        Point curPos = new Point((int)xPosition, (int)yPosition);

        return curPos;
    }
Not a bug
  • 4,286
  • 2
  • 40
  • 80
user2982527
  • 71
  • 2
  • 9
  • http://stackoverflow.com/questions/289434/how-to-make-a-java-thread-wait-for-another-threads-output?rq=1 - possible duplicate. – Gorbles Jan 24 '14 at 11:10
  • Sounds like you need to use `synchronized` and use `wait()` and `notify()` – Stewart Jan 24 '14 at 11:13
  • Well the timer() method is synchronized but I dont know what to do here: else if(dest.pas == false){ // here plane must wait till airfield is not blocked and land - I dont know how to do this – user2982527 Jan 24 '14 at 11:18
  • don't call wait method. It is not best practice. – hellzone Jan 24 '14 at 12:30

3 Answers3

2

OK, so your plane is a thread and your airfields are the shared resource. So to make your plane (thread) wait, you'll need to synchronized on the shared resource (airfield). You'll probably do something like this.

For take off,

public void tryStart() {
    synchronized(source) { // try to obtain source lock
        try {
            Thread.sleep(5000); // lock it for 5 seconds.
        }
        catch(Exception ignore) {
            // You'll need to decide what to do if something interrupts the thread while it's "sleeping" (ie. locked) on the source airfield. Normally, this should not happen.
        }
    }
    // After 5 seconds, releases lock on airfield "source" and Plane starts flying
}

For landing,

public void tryLadowanie() {
    synchronized(dest) { // try to obtain dest lock
        // successfully obtained lock.
        // perform your landing
    }
    // plane landed and releases "dest" resource for other planes (ie. threads)
}

For a more complete picture of plane flying.

public void run(){
    while(true){
        tryStart(); // take off from source
        lecimy();   // fly the plane. Method will only return when plane reaches destination.
        tryLadowanie(); // land the plane
        source = dest;
        dest = Rand(source); // returns a new destination but can't be the same as source
    }
}


public void tryStart(){
    synchronized(source) {
        try {
            Thread.sleep(5000);
        }
        catch(Exception ignore) { }
    }
}

public void tryLadowanie(){
    synchronized(dest) {
        // land the plane
    }
}
anonymous
  • 1,317
  • 8
  • 7
  • Well but i have a synchronized method timer() in class Lotnisko (airfield) that makes pas = false (shared resource) for 5 sec. I was thinking about hmm to loop a thread for a while - till pas == true – user2982527 Jan 24 '14 at 11:28
  • I can't see a need for the variable pas to synchronize the threads (ie. planes). When you put synchronized(source) { }, it means there can be only 1 plane that can go in to execute the code inside. Other threads (ie. planes) will automagically wait if there is another plane already inside taking off/landing. So by using synchronized(), it handles all the waiting and unwaiting for you. You don't have to do it manually. In your case, I also don't see a need for you to call wait() and notify(). – anonymous Jan 24 '14 at 11:35
  • Can You take a look on lecimy() method and tryLadowanie() inside of it ? When this: while( (xPosition != xTarget) && (yPosition != yTarget) ){ ends I want to tryLadowanie() and something is wrong with it... – user2982527 Jan 24 '14 at 11:42
  • I can only assume update() works correctly. update() supposed to modify the plane's coordinates (xPosition and yPosition) to fly towards the destination coordinates. I've updated the solution for what I think you'll need. – anonymous Jan 24 '14 at 12:54
0

Not a complete answer but wait method is used to wait the thread and notify is used to wake up the thread that is in wait.

Check this for more info on wait and notify method: http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait() http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#notify()

Mohammad Ashfaq
  • 1,333
  • 2
  • 14
  • 38
0

Use general java object exp. Object lock=new Object(); To wait : Synchronized(lock) { lock.wait(); } To release or free the lock from another thread On same lock object Synchronized(lock) { lock.notify(); }

java seeker
  • 1,246
  • 10
  • 13