-
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){}
}
}
-
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) {
}
}
}
-
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 :-)
-
you're welcome.
Happy Holidays
-
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
-
Forum Rules
|
Development Centers
-- Android Development Center
-- Cloud Development Project Center
-- HTML5 Development Center
-- Windows Mobile Development Center
|