Threading: wait /notify...please help !


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 5 of 5

Thread: Threading: wait /notify...please help !

  1. #1
    Join Date
    Aug 2004
    Posts
    37

    Threading: wait /notify...please help !

    Hi guys...
    my question is about implementation of wait and notify to simulate threading...here is the Problem description:
    I have an application to simulate 2 trains travelling in the same direction on a loop from station, through a tunnel and back to the station ;normaly on 2 seperate tracks.however both tracks pass through the tunnel wich has one single track: so there should be one train at a time in the tunnel...

    what i need is to rewrite method useTunnel() given below so that train 1 and 2 are allowed to enter tunnel in strict rotation:train 2 should be allowed to enter first then train 1 then 2 and so on...method useTunnel should contain code to enforce the ordring of which train can enter at a given time...for this we should use wait and notify and maybe change the Tunnel constractor...how can i do this?

    the code is below (classes Train.java , Tunnel.java ans Simulate.java)

    many thanks for helping

    //Train class
    public class Train extends Thread
    {

    private int id; // id identifies each train

    public Train(int id) {
    // each train has a different identifing number
    this.id = id;
    }

    private static Tunnel tun = new Tunnel(); // only one tunnel

    public void run() {
    // each train makes 2 loops
    for (int j=0; j < 2; j++) {
    System.out.println("Train " + id + " leaves station");

    travel(10); // train takes 10 time units to travel from station to tunnel
    System.out.println("Train " + id + " arrives at tunnel");


    tun.useTunnel(this); // current train uses tunnel


    travel(15); // train takes 15 time units to travel from tunnel to station

    System.out.println("Train " + id + " arrives at station");
    travel(5); // train stays in station for 5 time units
    }
    }

    public int getId () {
    return id;
    }

    public void travel(int time) {
    int limit = 500000*id;
    for (int j=0; j < time; j++) {
    for (int k=0; k < limit; k++) {double r = j / 2 * 2;}
    }
    }

    }

    //Tunnel class
    public class Tunnel
    {
    public void Tunnel () {}

    public void useTunnel (Train t) {
    /* the tunnel is a shared resource
    between Train 1 and 2 .so we should use
    a synchronized block to lock the object "Tunnel"
    from being accessed simultaneousely by Train 1 and 2
    */
    synchronized(this){


    System.out.println("Train " + t.getId() + " enters tunnel");
    t.travel(20); // train takes 20 time unit to go through tunnel
    System.out.println("Train " + t.getId() + " exits tunnel");
    }
    }
    }
    //Simulate class
    public class Simulate
    {
    public static void main(String [] args) {

    // ***************************************
    Train t1=new Train(1);
    t1.start();
    Train t2=new Train(2);
    t2.start();

    // Keeps output on screen until Return is pressed

    System.out.println("Type return to terminate program");
    try {
    System.in.read();
    }
    catch (IOException e){}
    }

    }

  2. #2
    Join Date
    Nov 2004
    Location
    Minnesota
    Posts
    99
    How about this?
    Code:
    package simulation;
    
    import java.io.IOException;
    
    //Tunnel class
    class Tunnel {
      
      public int allowed;
    
      public Tunnel(int first) {
        allowed = first;
      }
    
      public void useTunnel(Train t) {
    
        /*
         * the tunnel is a shared resource between Train 1 and 2 .so we should use a
         * synchronized block to lock the object "Tunnel" from being accessed
         * simultaneousely by Train 1 and 2
         * 
         * if t is not allowed, wait
         */
        if (t.getId() != allowed) {
          System.out.println("Train " + t.getId() + " not allowed to enter tunnel.  Waiting.");
          synchronized (this) {
            try {
              this.wait();
            } catch (InterruptedException ie) {
              ie.printStackTrace();
            }
          }
        }
    
        //original code: synchronized (this) {
        System.out.println("Train " + t.getId() + " enters tunnel");
        t.travel(20); // train takes 20 time unit to go through tunnel
        System.out.println("Train " + t.getId() + " exits tunnel");
        //}
    
        // Change allowed and wake up waiter
        synchronized (this) {
          allowed = (allowed == 1) ? 2 : 1;
          System.out.println("Train " + allowed + " is ok to enter tunnel.");
          this.notify();
        }     
      }
    }
    
    //Train class
    
    class Train extends Thread {
    
      private static Tunnel tun = new Tunnel(1); // only one tunnel
    
      //  Simulate class
    
      private int id; // id identifies each train
    
      public Train(int id) {
        // each train has a different identifing number
        this.id = id;
      }
    
      public void run() {
        // each train makes 2 loops
        for (int j = 0; j < 3; j++) {
          System.out.println("Train " + id + " leaves station");
    
          travel(10); // train takes 10 time units to travel from station to tunnel
          System.out.println("Train " + id + " arrives at tunnel");
    
          tun.useTunnel(this); // current train uses tunnel
    
          travel(15); // train takes 15 time units to travel from tunnel to station
    
          System.out.println("Train " + id + " arrives at station");
          travel(5); // train stays in station for 5 time units
        }
      }
    
      public int getId() {
        return id;
      }
    
      public void travel(int time) {
        int limit = 500000 * id;
        for (int j = 0; j < time; j++) {
          for (int k = 0; k < limit; k++) {
            double r = j / 2 * 2;
          }
        }
      }
    
    }
    
    public class Simulate {
    
      public static void main(String[] args) {
    
        // ***************************************
        Train t1 = new Train(1);
        t1.start();
        Train t2 = new Train(2);
        t2.start();
    
        // Wait for both Trains to finish.
        try {
    	    t1.join();
    	    t2.join();
        } catch (InterruptedException ie ) {
          ie.printStackTrace();
        }
    
        // Keeps output on screen until Return is pressed
        System.out.println("Type return to terminate program");
        try {
          System.in.read();
        } catch (IOException e) {
        }
      }
    }

  3. #3
    Join Date
    Aug 2004
    Posts
    37
    wow !
    this is very cool and it's working fine :-)

    many thanks for you man...i'm very gratefull ...
    i had only to make few changes if i want the Train 2 to be allowed first (new Tunnel(2))...and that's it
    I will keep on testing it for all cases (big number of loops) and will notify you...but i'm sure this is the wright solution .

    many thanks :-)

  4. #4
    Join Date
    Nov 2004
    Location
    Minnesota
    Posts
    99
    you're welcome.

    Happy Holidays

  5. #5
    Join Date
    Aug 2004
    Posts
    37

    Smile

    thanks and happy hollidays for you too :-)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center