【发布时间】:2014-11-23 01:25:25
【问题描述】:
我正在寻找一种使用信号量来解决哲学家就餐问题的方法,但我一直不知道应该如何去做。我在下面包含了我的代码。
class ChopStick{
private int count;
private boolean inuse;
Lock lock = new ReentrantLock();
Condition notInUse = lock.newCondition();
public ChopStick(){
inuse = false;
}
public void pickUp(){
lock.lock();
try{
while(inuse){
try{
notInUse.await();
}catch(InterruptedException e){}
}
inuse = true;
}finally{lock.unlock();}
}
public void putDown(){
lock.lock();
try{
inuse = false;
notInUse.signal();
}finally{lock.unlock();}
}
}
class Philosopher extends Thread{
Semaphore sem;
private ChopStick ch1,ch2; //chopsticks
private int phil; //philosopher id
public Philosopher(int p, ChopStick left, ChopStick right, Semaphore s){
phil = p;
ch1 = left;
ch2 = right;
sem = s;
}
public void run() {
while(true){
try {
sem.acquire();
} catch (InterruptedException e) {}
think(phil);
//pickup chopsticks
ch1.pickUp();
ch2.pickUp();
eat(phil);
//putdown chopsticks
ch1.putDown();
ch2.putDown();
sem.release();
}
}
我在想当哲学家拿起筷子时使用sem.acquire(),然后当他们用完sem.release(),但我不确定这是否正确。是吗?
编辑所以我已经实现了这个。它似乎有效,但我不确定。
class ChopStick{
private Semaphore sem;
public ChopStick(Semaphore s){
sem = s;
}
public void pickUp(){
try{
sem.acquire();
}catch(InterruptedException e){}
}
public void putDown(){
sem.release();
}
【问题讨论】:
-
我知道它是如何工作的,我正在寻找使用信号量来解决。
-
@Strobes 新代码可能会陷入死锁,请参阅我的答案的编辑以了解防止这种情况的方法
-
哦,谢谢您的回复。如果我没记错的话,另一种可能的方法是让其中一位哲学家右撇子?从而消除死锁。只是一个想法。
-
@Strobes 是的,防止死锁的一种通用方法是为每个资源分配唯一的优先级,并要求先获取高优先级资源,然后再获取低优先级资源;在这种情况下,您将为 N 根筷子中的每根分配一个从 1 到 N 的优先级,因此除了一位哲学家之外,左边的筷子将具有优先级
i,而右边的筷子将具有优先级i+1(即除了一位哲学家以外,其他人都是左撇子),但一位哲学家的左筷子优先级为 N,右筷子优先级为 1(即一位哲学家是右撇子)
标签: java multithreading semaphore