Реализация алгоритма Java - Dekkers приводит к двум потокам в критической секции - PullRequest
0 голосов
/ 25 февраля 2019

Я пытаюсь реализовать алгоритм Деккерса для сценария, где есть две железные дороги, и есть точка, где они используют одну и ту же часть пути.Только один поезд должен быть допущен к этому участку за один раз, и один поезд может проходить столько раз подряд, сколько ему хотелось бы, если только не ходят оба других поезда и он не готов пройти через него.

Нижеэто код моей реализации для первого железнодорожного пути.

while (allowed) {
        choochoo();
        setWantToUseTrack(0,true);
        while (getWantToUseTrack(1)) {
            if (getTurn() != 0) {
                setWantToUseTrack(0,false);
                while (getTurn() != 0) {
                    //wait loop
                }
                setWantToUseTrack(0, true);
            }
        }
        //critical section starts
        crossPass();
        //critical section ends
        setTurn(1);
        setWantToUseTrack(0,false);
    }
}

Ниже приведен код для моей реализации второго железнодорожного пути.

while (allowed) {
        choochoo();
        setWantToUseTrack(1,true);
        while (getWantToUseTrack(0)) {
            if (getTurn() != 1) {
                setWantToUseTrack(1,false);
                while (getTurn() != 1) {
                    //wait loop
                }
                setWantToUseTrack(1,true);
            }
        }
        //critical section starts
        crossPass();
        //critical section ends
        setTurn(0);
        setWantToUseTrack(1,false);
    }

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

1 Ответ

0 голосов
/ 25 февраля 2019

Возможно, что происходит следующее (только один пример):

  1. Во втором треке setWantToUseTrack(1,false); вызывается.
  2. В первом треке предикатпроверено: while (getWantToUseTrack(1)), чтобы второй поток не останавливался в цикле while.

    Это абсолютно осуществимо, поскольку первая дорожка может быть остановлена ​​с помощью choochoo(); до (1.), а вторая дорожка до (2.).

  3. Метод getWantToUseTrack возвращаетfalse для 0 и 1.

Создание цикла для перехвата потока до тех пор, пока не освободится критическая секция, немного опасно.Вы можете захотеть сделать этот раздел потокобезопасным, используя synchronized с crossPass определением.

...