DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

+ Reply to Thread
Results 1 to 5 of 5
  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 :-)

Bookmarks

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


Top DevX Stories

Easy Web Services with SQL Server 2005 HTTP Endpoints
JavaOne 2005: Java Platform Roadmap Focuses on Ease of Development, Sun Focuses on the "Free" in F.O.S.S.
Wed Yourself to UML with the Power of Associations
Microsoft to Add AJAX Capabilities to ASP.NET
IBM's Cloudscape Versus MySQL


Sponsored Links