【问题标题】:Java Dining Philosophers Dead Lock with KoordinatorJava Dining Philosophers Dead Lock with Koordinator
【发布时间】: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


【解决方案1】:

我发现了问题。我需要在Monitor 的方法的开头创建一个lock。没有那个我就变成了Illegal State Exception

监视器现在看起来像这样:

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 takeForks(int id) throws InterruptedException {
       this.lock.lock();
       try {
            while (forks[id] != 2) {
                 readyToEatCondition[id].await();
            }
            forks[(id + 1) % anzahlPhilosophen] = forks[(id + 1) % anzahlPhilosophen] - 1;
            forks[(id - 1 + anzahlPhilosophen) % anzahlPhilosophen] = forks[(id - 1 + anzahlPhilosophen) % anzahlPhilosophen] - 1;
        } finally {
            this.lock.unlock();
        }
    }

    public void releaseForks(int id) {
        this.lock.lock();
        try {
            forks[(id + 1) % anzahlPhilosophen] = forks[(id + 1) % anzahlPhilosophen] + 1;
            forks[(id - 1 + anzahlPhilosophen) % anzahlPhilosophen] = forks[(id - 1 + anzahlPhilosophen) % anzahlPhilosophen] + 1;

            if (forks[(id + 1) % anzahlPhilosophen] == 2) {
                readyToEatCondition[(id + 1) % anzahlPhilosophen].signalAll();
            }
            if (forks[(id - 1 + anzahlPhilosophen) % anzahlPhilosophen] == 2) {
                readyToEatCondition[(id - 1 + anzahlPhilosophen) % anzahlPhilosophen].signalAll();
            }
        } finally {
            this.lock.unlock();
        }
    }
}

【讨论】:

    猜你喜欢
    • 2017-11-28
    • 1970-01-01
    • 2017-03-02
    • 2016-06-19
    • 2018-09-05
    • 1970-01-01
    • 2014-12-13
    • 1970-01-01
    • 2023-01-26
    相关资源
    最近更新 更多