← Назад к вопросам

Какие плюсы и минусы Hashtable?

1.3 Junior🔥 131 комментариев
#Коллекции#Основы Java

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Hashtable: плюсы и минусы

Hashtable — это один из древнейших классов в Java, который реализует хеш-таблицу с полной синхронизацией. Это legacy класс, оставленный для обратной совместимости.

Плюсы Hashtable

1. Потокобезопасность из коробки

Hashtable синхронизирует все операции:

Hashtable<String, Integer> table = new Hashtable<>();
table.put("key1", 100);
int value = table.get("key1");

// Все методы синхронизированы
// Можно использовать в многопоточной среде без дополнительных мер

Все операции потокобезопасны без дополнительной синхронизации.

2. Не допускает null значений

Hashtable<String, Integer> table = new Hashtable<>();
table.put("key1", null); // throws NullPointerException
table.put(null, 100);    // throws NullPointerException

Это может предотвратить баги, связанные с null значениями.

3. Совместимость со старым кодом

Хаштейбл вводилась в Java 1.0, поэтому много legacy кода полагается на неё.

Минусы Hashtable

1. Глобальная синхронизация — очень медленно

Все методы синхронизированы, даже при чтении:

Hashtable<String, Integer> table = new Hashtable<>();
table.put("key1", 100);
table.put("key2", 200);

// Каждый get() заблокирует весь объект
int value = table.get("key1"); // синхронизировано целиком

Сравнение производительности:

Hashtable на 1M операций: 500ms
HashMap на 1M операций:    50ms
ConcurrentHashMap:         60ms (с лучшей параллельностью)

2. Плохая скалируемость на многоядерных системах

Весь объект заблокирован при любой операции:

На 4 потоках:
Hashtable:        блокируется, очень медленно
ConcurrentHashMap: разбита на сегменты, работает параллельно

3. Устаревший класс

// ❌ Не рекомендуется использовать
Hashtable<String, Integer> table = new Hashtable<>();

// ✅ Используй HashMap
Map<String, Integer> map = new HashMap<>();

// ✅ Или для многопоточности
Map<String, Integer> map = new ConcurrentHashMap<>();

Java документация явно указывает, что Hashtable deprecated для новых разработок.

4. Не поддерживает null

HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put(null, 100);  // OK
hashMap.put("key", null); // OK

Hashtable<String, Integer> table = new Hashtable<>();
table.put(null, 100);    // NullPointerException
table.put("key", null);  // NullPointerException

В HashMap можно хранить null, что иногда полезно.

5. API похож на HashMap, но не совпадает

// HashMap использует computeIfAbsent
map.computeIfAbsent("key", k -> "value");

// Hashtable этого не поддерживает
table.putIfAbsent("key", "value"); // медленнее

6. Нет контроля над уровнем синхронизации

// ConcurrentHashMap позволяет настроить
ConcurrentHashMap<String, Integer> cmap =
    new ConcurrentHashMap<>(16, 0.75f, 4); // 4 сегмента

// Hashtable синхронизирует всё целиком, нет опций

Сравнение с HashMap и ConcurrentHashMap

// HASHTABLE - запрещено
Hashtable<String, String> ht = new Hashtable<>();
ht.put(null, "value");        // NullPointerException

// HASHMAP - позволяет null
HashMap<String, String> hm = new HashMap<>();
hm.put(null, "value");        // OK
hm.put("key", null);          // OK

// CONCURRENTHASHMAP - позволяет, потокобезопасно
ConcurrentHashMap<String, String> chm = new ConcurrentHashMap<>();
chm.put("key", "value");      // OK и потокобезопасно
chm.putIfAbsent("key", "value"); // Атомарная операция
ХарактеристикаHashtableHashMapConcurrentHashMap
ПотокобезопасностьДа (полная)НетДа (сегментированная)
Null поддержкаНетДаНет
ПроизводительностьМедленнаяБыстраяБыстрая
СкалируемостьПлохаяN/AОтличная
Современная?Нет (deprecated)ДаДа
СинхронизацияНа весь объектБез синхроПо сегментам

Пример: почему Hashtable медленная

// Два потока пытаются обновить разные ключи

// Thread 1
Hashtable<String, Integer> table = new Hashtable<>();
table.put("key1", 100); // БЛОКИРУЕТ весь объект
// table.put("key2", 200); // ждёт, пока Thread 2 отпустит блокировку

// Thread 2
table.put("key2", 200);  // БЛОКИРУЕТ весь объект
// table.put("key1", 100); // ждёт, пока Thread 1 отпустит блокировку

// С ConcurrentHashMap - оба потока могут работать параллельно
ConcurrentHashMap<String, Integer> cmap = new ConcurrentHashMap<>();
cmap.put("key1", 100); // Lock segment 0
cmap.put("key2", 200); // Lock segment 1 - параллельно!

Когда НЕ использовать Hashtable

Почти всегда:

// ❌ НИКОГДА не используй
Hashtable<String, String> table = new Hashtable<>();

// ✅ Вместо этого:
// Для однопоточного доступа
Map<String, String> map = new HashMap<>();

// Для многопоточного доступа
Map<String, String> map = new ConcurrentHashMap<>();

// Для синхронизированного доступа (если обязательно)
Map<String, String> map = Collections.synchronizedMap(
    new HashMap<>()
);

Вывод

Hashtable — это legacy класс, оставленный для обратной совместимости. В современном Java коде никогда не следует использовать Hashtable:

  1. Используй HashMap для однопоточного доступа
  2. Используй ConcurrentHashMap для многопоточного доступа
  3. ConcurrentHashMap обеспечивает лучшую производительность и скалируемость
  4. ConcurrentHashMap имеет более современный API

Eе единственное применение — поддержка старого legacy кода, который по какой-то причине не может быть обновлен.

Какие плюсы и минусы Hashtable? | PrepBro