In: Computer Science
Single Lane Bridge Problem : Java Threads
Given :
//Use ReentrantLock for mutual exclusion
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class bridge { private final ReentrantLock myLock = new ReentrantLock(); public bridge(){ } public String cross(){ myLock.lock(); try { return "crossing the bridge"; } finally { myLock.unlock(); } } }
public class lane extends Thread { int cars; bridge Bridge; public lane(int Cars1, bridge Bridge1) { cars = Cars1; Bridge = Bridge1; } public void run(){ for(int x=0;x
//Important clue :
<Thread-ID> waiting to cross
This means that this thread is now competing for the lock and will have to wait its turn.
- Once a thread has gained access to the critical section it should output:
<Thread-ID> crossing the bridge
- It takes different cars a different amount of time to cross the bridge, so your code should simulate this by sleeping for a random amount of time when accessing the critical section.
- Once a car has left the bridge, your program should output:
<Thread-ID> exiting
- Threads can enter the critical section in any order.
Create main such that the output is as follows :
Thread-0 waiting to cross
Thread-0 crossing the bridge
Thread-0 exiting
Thread-1 waiting to cross
Thread-2 waiting to cross
Thread-1 crossing the bridge
Thread-1 exiting
Thread-2 crossing the bridge
Thread-2 exiting
.....
.....
.....
.....
import java.util.concurrent.*;
// Defines a class SingleLaneBridgeDriver
public class SingleLaneBridgeDriver
{
// main method definition
public static void main(String[] ss)
{
// Creates an object of the class Bridge
final Bridge bridge = new Bridge();
// Defines an anonymous object for the class Thread
// for right to left lane
Thread laneRightToLeft = new Thread( new Runnable()
{
// Overrides the run() method
@Override
public void run()
{
// Loops infinitely
while(true)
{
// Creates an object of the class Car
Car currentCar = new Car(bridge);
// Creates a Thread for Car class object
Thread threadRL = new Thread(currentCar);
// Sets the name of the car to thread id
currentCar.setCarName("Thread: " + threadRL.getId());
// Calls the start() method to start the thread
threadRL.start();
// Try block for pause time
try
{
TimeUnit.SECONDS.sleep((long)(Math.random()*10));
}// End of try block
// Catch block to handle InterruptedException for sleep() method
catch(InterruptedException exp)
{
exp.printStackTrace();
}// End of catch
}// End of while loop
}// End of method
});// End of anonymous class
// Defines an anonymous object for the class Thread
// for right to left lane
Thread laneLeftToRight = new Thread( new Runnable()
{
// Overrides the run() method
@Override
public void run()
{
// Loops infinitely
while(true)
{
// Creates an object of the class Car
Car currentCar = new Car(bridge);
// Creates a Thread for Car class object
Thread threadLR = new Thread(currentCar);
// Sets the name of the car to thread id
currentCar.setCarName("Thread: " + threadLR.getId());
// Calls the start() method to start the thread
threadLR.start();
// Try block for pause time
try
{
TimeUnit.SECONDS.sleep((long)(Math.random()*10));
}// End of try block
// Catch block to handle InterruptedException for sleep() method
catch(InterruptedException exp)
{
exp.printStackTrace();
}// End of catch
}// End of while loop
}// End of method
});// End of anonymous class
// Calls the start method for both laneRightToLeft and
// laneLeftToRight
laneRightToLeft.start();
laneLeftToRight.start();
}// End of main method
}// End of driver class
// Defines class Bridge
class Bridge
{
// Declares an object of class Semaphore
private final Semaphore semaphore;
// Default constructor definition
public Bridge()
{
semaphore = new Semaphore(1);
}// End of constructor
// Method to implement mechanism of crossing bridge
public void crossBridge(Car newCar)
{
// try block begins
try
{
// Displays the name of the waiting car
System.out.printf("Car %s is waiting to cross the bridge.\n",
newCar.getCarName());
// Used to wait until a permit is not available
semaphore.acquire();
// Displays the name of the crossing car
System.out.printf("Car %s is crossing the bridge.\n",
newCar.getCarName());
// Calculates the time duration
long stopTime = (long)(Math.random() * 10);
// Sleeps for the duration of stopTime
TimeUnit.SECONDS.sleep(stopTime);
}// End of try block
// Catch block to handle InterruptedException for sleep() method
catch(InterruptedException exp)
{
exp.printStackTrace();
}// End of catch block
// finally block to display the crossed bridge car name
finally
{
System.out.printf("Car %s has crossed the bridge.\n",
newCar.getCarName());
semaphore.release();
}// End of finally block
}// End of method
}// End of class
// Defines a class Car which implements Runnable interface
class Car implements Runnable
{
// To store name of the car
private String carName;
// Declares an object of class bridge
private Bridge bridge;
// Parameterized constructor to assign parameter Bridge object to
// instance object
public Car(Bridge bri)
{
bridge = bri;
}// End of constructor
// Overrides the run() method of Runnable interface
public void run()
{
// Calls the method to cross the bridge
bridge.crossBridge(this);
}// End of method
// Method to return car name
public String getCarName()
{
return carName;
}// End of method
// Method to set the car name
public void setCarName(String name)
{
carName = name;
}// End of method
}// End of class Car
Sample Output:
Car Thread: 17 is waiting to cross the bridge.
Car Thread: 16 is waiting to cross the bridge.
Car Thread: 17 is crossing the bridge.
Car Thread: 18 is waiting to cross the bridge.
Car Thread: 17 has crossed the bridge.
Car Thread: 16 is crossing the bridge.
Car Thread: 16 has crossed the bridge.
Car Thread: 18 is crossing the bridge.
Car Thread: 19 is waiting to cross the bridge.
Car Thread: 20 is waiting to cross the bridge.
Car Thread: 18 has crossed the bridge.