Код имеет критический недостаток и не потокобезопасен. Хотя он использует синхронизацию, реализация содержит состояние гонки, которое вызывает некорректное поведение в многопоточных сценариях.
Код использует два отдельных блока synchronized вместо одного атомарного блока. Это создаёт брешь, где:
queue.wait() в первом синхронизированном блокеpoll() на пустой очередиIllegalStateExceptionКритическая проблема в том, что поток может быть уведомлён о доступных данных, но к тому моменту, когда он выполнит queue.poll(), другой поток уже может эти данные забрать. Два отдельных синхронизированных блока нарушают атомарность, необходимую для безопасного параллельного доступа.
Объедини оба блока в один синхронизированный регион:
synchronized (queue) {
try {
while (queue.isEmpty()) {
queue.wait();
}
retVal = queue.poll();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
while вместо if, чтобы перепроверить состояние очереди после пробужденияЭто гарантирует взаимное исключение и предотвращает состояние гонки, которое возникает, когда несколько потоков просыпаются одновременно.
Условие гонки в исходном коде возникает потому, что поток может получить уведомление о доступности данных, но другой поток может потребить эти данные до того, как уведомленный поток выполнит poll().
Новый — ещё не проверен сообществом
Вы