这是哲学家就餐问题的又一实施,这是家庭作业的问题,我将在这里展示我迄今为止尝试:另一个哲学家就餐并发问题
/**
* DPServer.java
* <p>
* This class implements the methods called by the philosophers
*/
package cc;
import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class DPServer {
private static Lock chopstick[] = new Lock[5]; // Create chopstick locks
private static Lock mutex = new ReentrantLock(true);
private static int MAX_EAT_TIME = 5000; // maximum eating time in milliseconds
private static int MAX_THINK_TIME = 5000; // maximum thinking time in milliseconds
private static Random r = new Random(0);
// default constructor for DPServer class
public DPServer() {
for (int i = 0; i < 5; i++) {
chopstick[i] = new ReentrantLock(true);
} // end for
} // end DPServer default constructor
// called by a philosopher when they wish to eat
public void takeChopsticks(int philosopherNumber) {
// acquire chopstick[philosopherNumber] and chopstick[(philosopherNumber + 1) mod 5]
System.out.println("Acquiring chopstick[" + philosopherNumber + "] and chopstick[" + ((philosopherNumber + 1) % 5) + "]");
chopstick[philosopherNumber].lock();
chopstick[(philosopherNumber + 1) % 5].lock();
// eat for a random number of milliseconds
int eatTime = r.nextInt(MAX_EAT_TIME);
System.out.println("Philosopher " + philosopherNumber + " is eating for " + eatTime + " milliseconds");
try {
Thread.sleep(eatTime);
} catch (InterruptedException ex) {
System.out.println("Philosopher " + philosopherNumber + " eatTime sleep was interrupted");
}
} // end takeChopsticks
// called by a philosopher when they are finished eating
public void returnChopsticks(int philosopherNumber) {
// release chopstick[philosopherNumber] and chopstick[(philosopherNumber + 1) mod 5]
System.out.println("Releasing chopstick[" + philosopherNumber + "] and chopstick[" + ((philosopherNumber + 1) % 5) + "]");
chopstick[(philosopherNumber + 1) % 5].unlock();
chopstick[philosopherNumber].unlock();
// think for a random number of milliseconds
int thinkTime = r.nextInt(MAX_THINK_TIME);
System.out.println("Philosopher " + philosopherNumber + " is thinking for " + thinkTime + " milliseconds");
try {
Thread.sleep(thinkTime);
} catch (InterruptedException ex) {
System.out.println("Philosopher " + philosopherNumber + " thinkTime sleep was interrupted");
}
}
}
// implementation of the Dining Philosopher class
package cc;
public class DPhilosopher {
private int dpNum;
private DPServer dpServ;
// value constructor for the DPhilosopher class
public DPhilosopher(int num, DPServer d) {
dpNum = num;
dpServ = d;
} // end DPhilosopher value constructor
public void DPEatThink() {
while (true) {
// get ready to eat
System.out.println("Philosopher " + dpNum + " is getting ready to eat");
dpServ.takeChopsticks(dpNum);
// finish eating
System.out.println("Philosopher " + dpNum + " is finished eating");
dpServ.returnChopsticks(dpNum);
}
}
public static void main(String[] args) {
DPServer dps = new DPServer();
DPhilosopher dp[] = new DPhilosopher[5];
Thread dpThread[] = new Thread[5];
// Create and launch the DPhilosopher threads
for (int i = 0; i < 5; i++) {
dp[i] = new DPhilosopher(i, dps);
final int finalI = i;
dpThread[i] = new Thread(new Runnable() {
@Override
public void run() {
dp[finalI].DPEatThink();
}
});
dpThread[i].start();
}
} // end main
}
大部分代码给出了准备,除了takeChopsticks()
而需要改变returnChopsticks()
方法和我所做的就是将这样的:
chopstick[(philosopherNumber + 1) % 5].lock();
chopstick[philosopherNumber].lock();
和
chopstick[(philosopherNumber + 1) % 5].unlock();
chopstick[philosopherNumber].unlock();
我知道这不是线程安全的,并且这个link也保证它。真正神话的是老师希望我们用DPServer#mutex
锁来解决这个问题,我可以锁住/解锁takeChopsticks()
和returnChopsticks()
中的互斥锁,锁定和解锁2把锁(chopstick [philosopherNumber] .lock(); chopstick [(philosopherNumber + 1 )%5] .lock();),但这会造成死锁。
我只是没有看到如何解决这个只使用一个互斥体ReentrantLock。
任何人都可以帮助我吗?
在此先感谢。
我不确定我的理解。为什么你需要锁定解锁互斥锁的位置?通过在锁定代码周围放置一个锁,每次只有一位哲学家可以捡起筷子。如果其中一根筷子不可用,则不希望锁定防止邻居哲学家放下筷子。 –
@KyleA当我说放置锁定时,我的意思是mutex.loc();逻辑(),mutex.unlock();这是对的,这没有多大意义,但我被给了这个模板,并以某种方式与这个互斥体(ReentrantLock实例)将解决这个问题。 – user3143318
是的,我的意思是一把锁可以绕过锁定逻辑,所以'锁;拾起筷子1;拾取筷子2;解锁'。这样你就无法解决僵局,因为只有一个哲学家可以在任何时候拿起筷子。 –