【发布时间】:2019-12-19 17:52:11
【问题描述】:
我正在尝试为经典的单车道桥梁问题提供解决方案,其中单车道桥梁连接两个村庄。它只使用一个线程,因此如果农民同时跳到桥的任一侧,可能会陷入僵局。到目前为止,这是我的解决方案,但我不确定如何让它不饿死?
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;
}
}
【问题讨论】:
-
你的代码有很多问题,但死锁的风险不是其中之一。
-
至于确保不饿死——你读过
Semaphore的Javadoc吗?有一个你没有使用的构造函数。 . . -
@ruakh 是的,我阅读了 Javadoc,您指的是什么?
-
我的代码有什么问题?
-
这对于评论来说太大了,所以我已经在答案中发布了它。 (抱歉耽搁了。)
标签: java deadlock semaphore java-threads starvation