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

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

Ответ

Да, но с важными оговорками.

Класс Vector считается потокобезопасным, потому что его ключевые методы (такие как add, get, remove) объявлены с модификатором synchronized. Это обеспечивает базовую синхронизацию при вызовах из разных потоков.

Vector<String> vector = new Vector<>();
vector.add("Item1"); // Этот вызов синхронизирован

Однако Vector часто не рекомендуется к использованию по следующим причинам:

  • Низкая производительность: Синхронизация на уровне каждого метода создает высокие накладные расходы, даже в однопоточных сценариях.
  • Не гарантирует безопасность составных операций: Потокобезопасность отдельных методов не защищает последовательность вызовов.
// НЕПОТОКОБЕЗОПАСНО: между проверкой и добавлением другой поток может изменить вектор
if (!vector.contains("item")) {
    vector.add("item");
}

Современные альтернативы:

  • Collections.synchronizedList(new ArrayList<>()): Позволяет явно контролировать, когда нужна синхронизация.
  • CopyOnWriteArrayList: Идеален для сценариев, где операции чтения значительно преобладают над операциями записи.
  • Коллекции из java.util.concurrent: Например, ConcurrentLinkedQueue или ConcurrentHashMap для более специфичных случаев.