Как бросить исключение, когда в столовой возникает проблема философов? - PullRequest
0 голосов
/ 13 апреля 2020

Ниже моя проблема с обеденными философами. Когда я его выполняю, иногда возникает тупик, и программа перестает работать, например, в следующем примере:

Филозоф № 0 принимает вилы
Филозоф № 4 принимает вилки
Филозоф № 4 взял вилку на слева
Филозоф № 3 берет вилы
Филозоф # 1 берет вилы
Филозоф № 2 берет вилы
Филозоф № 3 развил вилку слева
Филозоф № 1 взял вилку слева
Filozof # 0 взял вилку слева
Filozof # 2 взял вилку слева

Я хочу создать исключение в последнем потоке, который бы завершил тупик. Я не хочу решать проблему тупика. Что мне нужно, это бросить исключение. Как я могу это сделать?

public class Philosopher extends Thread implements Runnable {
            private int forkLeft;
            private int forkRight;
            private int index;

            public Philosopher(int index) {
                forkLeft = index;
                forkRight = (index + 1) % 5;
                this.index = index;
            }

            @Override
            public void run() {
                // Endless life of a philosopher
                while (true) {
                    takeForks();
                    eat();
                    putDownForks();
                    think();
                }
            }

            /**
             * Take left and right forks
             */
            private void takeForks() {
                System.out.printf("Filozof#%d is taking forks\n", index);
                Table.takeFork(forkLeft);
                System.out.printf("Filozof#%d took fork at left\n", index);
                Table.takeFork(forkRight);
                System.out.printf("Filozof#%d took fork at right\n", index);
            }

            /**
             * Put left and right forks down
             */
            private void putDownForks() {
                System.out.printf("Filozof#%d is putting forks down\n", index);
                Table.putDownFork(forkLeft);
                System.out.printf("Filozof#%d put left fork down\n", index);
                Table.putDownFork(forkRight);
                System.out.printf("Filozof#%d put right fork down\n", index);
            }

            /**
             * Eat for a while
             */
            private void eat() {
                System.out.printf("Filozof#%d is now eating\n", index);
                sleep();
            }

            /**
             * think for a while
             */
            private void think() {
                System.out.printf("Filozof#%d is now thinking\n", index);
                sleep();
            }

            private void sleep() {
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }


    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    public class Table {
        public static Lock[] forks;
        public static Philosopher[] philosophers;

        public static void main(String[] args) {
            philosophers = new Philosopher[5];
            forks = new Lock[5];

            for (int i = 0; i < philosophers.length; i++) {
                philosophers[i] = new Philosopher(i);
                forks[i] = new ReentrantLock();
            }

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

        /**
         * Locks a fork with given index
         * @param fork index of the fork
         */
        public static void takeFork(int fork) {
            forks[fork].lock();
        }

        /**
         * unlocks a fork with given index
         * @param fork index of the fork
         */
        public static void putDownFork(int fork) {
            forks[fork].unlock();
        }
    }

1 Ответ

0 голосов
/ 14 апреля 2020

Вы не хотите генерировать исключение при возникновении тупика, вы просто должны предотвратить его возникновение. Тупик возникает из-за того, что вы не снимаете блокировки в том порядке, в котором они были взяты. Чтобы избежать этого, просто отпустите замки в том же порядке, в котором вы их приобрели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...