Является ли класс Stack в Java потокобезопасным?

«Является ли класс Stack в Java потокобезопасным?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Нет. Класс java.util.Stack не является потокобезопасным (non-thread-safe). Его методы не синхронизированы.

Проблема: При одновременной модификации одного экземпляра Stack из нескольких потоков может возникнуть состояние гонки (race condition), приводящее к повреждению данных или неопределенному поведению.

Решение 1: Внешняя синхронизация. Оберните все операции с Stack в synchronized блок.

Stack<Integer> stack = new Stack<>();
// Потокобезопасный доступ
synchronized(stack) {
    stack.push(42);
    Integer value = stack.pop();
}

Решение 2: Использование потокобезопасной альтернативы. Рекомендуется использовать классы из пакета java.util.concurrent.

  • ConcurrentLinkedDeque — полностью потокобезопасный, высокопроизводительный.
  • Collections.synchronizedStack(new Stack<>()) — возвращает синхронизированную (потокобезопасную) обёртку, но может иметь меньшую производительность из-за блокировок на уровне метода.
import java.util.concurrent.ConcurrentLinkedDeque;
Deque<Integer> safeStack = new ConcurrentLinkedDeque<>();
safeStack.push(42); // Потокобезопасная операция
Integer value = safeStack.pop();