【发布时间】:2015-11-15 11:01:54
【问题描述】:
我对餐饮哲学家问题有疑问。我想用Monitor 解决它。 Monitor 协调访问左右叉。
Monitor 使用 Array fork 和每个 Philosoph 的分叉数量。
如果哲学家i 可以(fork[i] == 2)他会从邻居那里拿一把叉子。如果他释放叉子,条目将再次增加。
这是我给哲学家的代码:
public class Philosoph {
protected volatile boolean isRunning = true;
protected final int id;
protected final Fork leftFork;
protected final Fork rightFork;
protected int eatCounter;
public Philosoph(int id, Fork leftFork, Fork rightFork) {
this.id = id;
this.leftFork = leftFork;
this.rightFork = rightFork;
eatCounter = 0;
}
public void eat() throws InterruptedException {
eatCounter++;
TimeUnit.MILLISECONDS.sleep(10);
}
public void think() throws InterruptedException {
TimeUnit.MILLISECONDS.sleep(5);
}
public void stop() {
isRunning = false;
}
}
public class KoordinierterPhilosph extends Philosoph implements Callable<Integer> {
Koordinator kord;
public KoordinierterPhilosph(Koordinator kord, int id, Fork leftFork, Fork rightFork) {
super(id, leftFork, rightFork);
this.kord = kord;
}
@Override
public Integer call() throws Exception {
while (isRunning) {
try {
think();
kord.takeFork(id);
eat();
kord.releaseFork(id);
} catch (InterruptedException ex) {
break;
}
}
return eatCounter;
}
}
这是我的监视器类:
public class Koordinator {
private int[] forks;
private int anzahlPhilosophen;
private ReentrantLock lock = new ReentrantLock();
private Condition[] readyToEatCondition;
public Koordinator(int anzahlPhilosophen) {
this.anzahlPhilosophen = anzahlPhilosophen;
forks = new int[anzahlPhilosophen];
readyToEatCondition = new Condition[anzahlPhilosophen];
for (int i = 0; i < anzahlPhilosophen; i++) {
forks[i] = 2;
readyToEatCondition[i] = lock.newCondition();
}
}
public void takeFork(int id) throws InterruptedException {
while (forks[id] != 2) {
readyToEatCondition[id].await();
}
forks[(id + 1) % anzahlPhilosophen] = forks[(id + 1) % anzahlPhilosophen] - 1;
if (id - 1 == -1) {
id = anzahlPhilosophen - 1;
} else {
id = id - 1;
}
forks[id] = forks[id] - 1;
}
public void releaseFork(int id) {
int idNew = 0;
forks[(id + 1) % anzahlPhilosophen] = forks[(id + 1) % anzahlPhilosophen] + 1;
if (id - 1 == -1) {
idNew = anzahlPhilosophen - 1;
} else {
idNew = id - 1;
}
forks[idNew] = forks[idNew] + 1;
if (forks[(id + 1) % anzahlPhilosophen] == 2) {
readyToEatCondition[(id + 1) % anzahlPhilosophen].signal();
}
if (forks[idNew] == 2) {
readyToEatCondition[idNew].signal();
}
}
}
这是我的主要日常:
public class Runner {
private static ExecutorService threadPool;
private static int gesamt = 0;
public static void main(String[] args) {
ExecutorService serv = Executors.newCachedThreadPool();
try {
dining(5, serv);
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(Ue7.DiningPhilosopher.Alg3.Runner.class.getName()).log(Level.SEVERE, null, ex);
}
serv.shutdown();
}
public static void dining(int anzahlPhilosopher, ExecutorService pool) throws InterruptedException, ExecutionException {
threadPool = pool;
Map<String, Future<Integer>> result = new HashMap<>();
KoordinierterPhilosph[] philosopher = new KoordinierterPhilosph[anzahlPhilosopher];
Koordinator kord = new Koordinator(anzahlPhilosopher);
for (int i = 0; i < anzahlPhilosopher; i++) {
philosopher[i] = new KoordinierterPhilosph(kord, i, null, null);
}
for (int i = 0; i < anzahlPhilosopher; i++) {
result.put("Philosoph " + i, threadPool.submit(philosopher[i]));
}
TimeUnit.SECONDS.sleep(10);
for (KoordinierterPhilosph p : philosopher) {
p.stop();
}
for (Map.Entry pair : result.entrySet()) {
Future<Integer> f = (Future<Integer>) pair.getValue();
int eatPro = f.get();
gesamt += eatPro;
System.out.println(pair.getKey() + " " + eatPro);
}
System.out.println("Gesamt: " + gesamt);
}
}
但我总是陷入僵局,但现在不知道为什么
【问题讨论】:
-
哲学家墙:(
-
那是什么意思?所有的哲学家都试图直接获得锁?
-
为什么从不使用同步关键字?
-
吃饭,哲学家需要两把叉子。方法 takeFork() 是否分配了 2 个分叉?那为什么不叫takeForks()呢?
标签: java multithreading threadpool future