I am attempting to provide a solution to the classic Single Lane Bridge Problem, where a single lane bridge connects two villages. It only uses one thread and so can become deadlocked if farmers jump on either side of the bridge at the same time. This is my solution so far, but I am not sure how to make it starvation-free?
public class SingleLaneBridge {
public static void main(String[] args)
{
final Bridge bridge = new Bridge();
Thread thNorthbound = new Thread( new Runnable() {
@Override
public void run() {
while(true) {
Farmer farmer = new Farmer(bridge);
Thread th = new Thread(farmer);
farmer.setName("North Farmer : "+ th.getId());
th.start();
try {
TimeUnit.SECONDS.sleep((long)(Math.random()*10));
} catch(InterruptedException iex) {
iex.printStackTrace();
}
}
}
});
Thread thSouthbound = new Thread( new Runnable() {
@Override
public void run() {
while(true) {
Farmer farmer = new Farmer(bridge);
Thread th = new Thread(farmer);
farmer.setName("South Farmer : "+th.getId());
th.start();
try {
TimeUnit.SECONDS.sleep((long)(Math.random()*10));
}
catch(InterruptedException iex)
{
iex.printStackTrace();
}
}
}
});
thNorthbound.start();
thSouthbound.start();
}
}
class Bridge {
private final Semaphore semaphore;
public Bridge() {
semaphore = new Semaphore(1);
}
public void crossBridge(Farmer farmer) {
try {
System.out.printf("Farmer trying to cross the bridge.\n",farmer.getName());
semaphore.acquire();
System.out.printf("Farmer crossing the bridge.\n",farmer.getName());
long duration = (long)(Math.random() * 10);
TimeUnit.SECONDS.sleep(duration);
}
catch(InterruptedException iex) {
iex.printStackTrace();
}
finally {
System.out.printf("Farmer as crossed the bridge.\n",farmer.getName());
semaphore.release();
}
}
}
class Farmer implements Runnable
{
private String name;
private Bridge bridge;
public Farmer(Bridge bridge)
{
this.bridge = bridge;
}
public void run() {
bridge.crossBridge(this);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}