Реализация алгоритма Java - Dekkers приводит к двум потокам в критической секции
Я пытаюсь реализовать алгоритм Деккерса для сценария, где есть две железные дороги, и есть точка, где они используют одну и ту же часть пути. Только один поезд должен быть допущен к этому участку за один раз, и один поезд может проходить столько раз подряд, сколько ему хотелось бы, если только оба поезда не повернуты и не готовы пройти через него.
Ниже приведен код моей реализации для первого железнодорожного пути.
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 ответ
Возможно, что произойдет следующее (только один пример):
- Во втором треке
setWantToUseTrack(1,false);
вызывается. В первом треке предикат проверяется:
while (getWantToUseTrack(1))
, чтобы второй поток не останавливался вwhile
петля.Это абсолютно осуществимо, поскольку первый трек может быть остановлен
choochoo();
до (1.) и второй дорожки до (2.).- метод
getWantToUseTrack
возвращаетсяfalse
для 0 и 1.
Создание цикла для перехвата потока до тех пор, пока не освободится критическая секция, немного опасно. Вы можете сделать раздел потокобезопасным, используя synchronized
с crossPass
определение.