首页 > 解决方案 > 餐饮哲学家java替代解决方案

问题描述

我在一本书上发现了 Java 中“餐饮哲学家问题”的替代解决方案:

public class Philosopher extends Thread {
private final int maxPause = 100;
private int bites = 10;

private Chopstick lower;
private Chopstick higher;
private int index;
public Philosopher(int i, Chopstick left, Chopstick right) {
    index = i;
    if (left.getNumber() < right.getNumber()) {
        this.lower = left;
        this.higher = right;
    } else {
        this.lower = right;
        this.higher = left;
    }
}

public void eat() {
    System.out.println("Philosopher " + index + ": start eating");
    pickUp();
    chew();
    putDown();
    System.out.println("Philosopher " + index + ": done eating");
}

public void pickUp() {
    pause();
    lower.pickUp();
    pause();
    higher.pickUp();
    pause();
}

public void chew() {
    System.out.println("Philosopher " + index + ": eating");
    pause();
}

public void pause() {
        try {
        int pause = AssortedMethods.randomIntInRange(0, maxPause);
        Thread.sleep(pause);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
   }

public void putDown() {
    higher.putDown();
    lower.putDown();
}

public void run() {
    for (int i = 0; i < bites; i++) {
        eat();
    }
}
}

public class Chopstick {
private Lock lock;
private int number;

public Chopstick(int n) {
    lock = new ReentrantLock();
    this.number = n;
}

public void pickUp() {
    lock.lock();
}

public void putDown() {
    lock.unlock();  
}

public int getNumber() {
    return number;
}
}

解决方案的文本是:

或者,我们可以用从 e 到 N - 1 的数字标记筷子。每个哲学家都试图先拿起编号较低的筷子。这实质上意味着每个哲学家都先选择左筷子,然后再选择右筷子(假设这是您标记它的方式),除了最后一位相反的哲学家。有了这个解决方案,哲学家就永远不能不拿着较小的筷子就拿着较大的筷子。这阻止了具有循环的能力,因为循环意味着较高的筷子将“指向”较低的筷子。

但对我来说还不清楚。有人可以帮我举个例子吗?

谢谢

- - 编辑 - - -

主类:

 public class Question {
public static int size = 3;

public static int leftOf(int i) {
    return i;
}

public static int rightOf(int i) {
    return (i + 1) % size;
}

public static void main(String[] args) {        
    Chopstick[] chopsticks = new Chopstick[size + 1];
    for (int i = 0; i < size + 1; i++) {
        chopsticks[i] = new Chopstick(i);
    }

    Philosopher[] philosophers = new Philosopher[size];
    for (int i = 0; i < size; i++) {
        Chopstick left = chopsticks[leftOf(i)];
        Chopstick right = chopsticks[rightOf(i)];
        philosophers[i] = new Philosopher(i, left, right);
    }

    for (int i = 0; i < size; i++) {
        philosophers[i].start();
    }       
}

}

标签: javadining-philosopher

解决方案


让我们有 3 位哲学家 - p1,p2,p3 和 3 根筷子 c1,c2,c3(筷子的索引等于number

然后创建 p1(c1, c2), p2(c2, c3), p3(c1, c3)

最坏的情况是:

  • p1 在 c1 上获得锁
  • 同时 p2 在 c2 上获得锁 -> 阻止 p1
  • p3 被 p1 阻塞(仍然持有 c1 锁)-> p2 可以自由获取 c3
  • p2 获取 c3 -> 完成并释放 c2 和 c3
  • p1 获取 c2 -> 完成并释放 c1 和 c2
  • p3 获取 c1 和 c3 -> 完成并释放 c1 和 c3

推荐阅读