В чем разница между ConcurrentHashMap и Collections.synchronizedMap (Map)?

Если значения хешируются, самым простым и тупым способом удаления дубликатов является использование set:

values = mygenerator()
unique_values = set(values)

Но не смотрите: наборы не помнят, какой порядок были изначально выбраны in. Таким образом, это скремблирует последовательность.

Функция ниже может быть лучше, чем set для вашей цели. Он отфильтровывает дубликаты, не вызывая каких-либо из других значений:

def nub(it):
    seen = set()
    for x in it:
        if x not in seen:
            yield x
            seen.add(x)

Вызов nub с одним аргументом, любым итерабельным значениями хеширования. Он возвращает итератор, который создает все те же элементы, но с удалением дубликатов.

572
задан lionheart 6 September 2016 в 07:11
поделиться

6 ответов

Для Ваших потребностей используйте ConcurrentHashMap. Это позволяет параллельную модификацию Карты от нескольких потоков без потребности заблокировать их. Collections.synchronizedMap(map) создает блокирующуюся Карту, которая ухудшит производительность, хотя гарантируют непротиворечивость (если используется правильно).

Использование вторая опция, если необходимо гарантировать непротиворечивость данных и каждый поток, должна иметь актуальное представление карты. Используйте первое, если производительность очень важна, и каждый поток только вставляет данные в карту с чтениями, происходящими менее часто.

408
ответ дан Yuval Adam 6 September 2016 в 17:11
поделиться

ConcurrentHashMap оптимизирован для параллельного доступа.

Доступы не блокируют целую карту, но используют более прекрасную гранулярную стратегию, которая улучшает масштабируемость. Существуют также функциональные enhanvements специально для параллельного доступа, например, параллельных итераторов.

4
ответ дан starblue 6 September 2016 в 17:11
поделиться

Вы правы приблизительно HashTable, можно забыть об этом.

Ваша статья упоминает то, что, в то время как HashTable и синхронизируемый класс обертки обеспечивают основную потокобезопасность, только позволяя один поток за один раз получить доступ к карте, это не 'истинная' потокобезопасность, так как много составных операций все еще требуют дополнительной синхронизации, например:

synchronized (records) {
  Record rec = records.get(id);
  if (rec == null) {
      rec = new Record(id);
      records.put(id, rec);
  }
  return rec;
}

Однако не думают, что ConcurrentHashMap простая альтернатива для HashMap с типичным synchronized блок как показано выше. Читайте этот статья для понимания ее запутанности лучше.

9
ответ дан eljenso 6 September 2016 в 17:11
поделиться
  • 1
    Ничего себе, очень всесторонний ответ! – Samuel Edwin Ward 7 August 2012 в 02:43

ConcurrentHashMap предпочтен, когда можно использовать его - хотя он требует, по крайней мере, Java 5.

Это разработано для масштабирования хорошо при использовании несколькими потоками. Производительность может быть незначительно более плохой, когда только единственный поток получает доступ к Карте за один раз, но значительно лучше когда несколько потоков получают доступ к карте одновременно.

я нашел запись в блоге , который воспроизводит таблицу от превосходного книжного Параллелизма Java На практике , который я полностью рекомендую.

Collections.synchronizedMap имеет смысл действительно, только если необходимо обернуть карту некоторыми другими характеристиками, возможно, своего рода заказанную карту, как TreeMap.

33
ответ дан SkyWalker 6 September 2016 в 17:11
поделиться
  • 1
    но тем не менее ячейка должна быть невыбранной для этого события, которое будет инициировано. Так это Вы остаетесь в той же ячейке, и Вы нажимаете его больше одного раза, привычка события быть инициированными – mustafabar 1 June 2009 в 01:02

"Проблемы масштабируемости" для Hashtable присутствуют точно таким же образом в Collections.synchronizedMap(Map) - они используют очень простую синхронизацию, что означает, что только один поток может получить доступ к карте одновременно.

Это не большая часть проблемы, когда у Вас есть простые вставки и поиски (если Вы не делаете это чрезвычайно интенсивно), но становится большой проблемой, когда необходимо выполнить итерации по всей Карте, которая может занять много времени для большой Карты - в то время как один поток делает это, все другие должны ожидать, если они хотят вставить или поиск что-нибудь.

ConcurrentHashMap использование очень сложные методы, чтобы уменьшить потребность в синхронизации и позволить параллельный доступ для чтения несколькими потоками без синхронизации и, что еще более важно, обеспечивают Iterator, который не требует никакой синхронизации и даже позволяет Карте быть измененной во время взаимодействия (хотя это не делает гарантий, будут ли элементы, которые были вставлены во время повторения, возвращены).

140
ответ дан Michael Borgwardt 6 September 2016 в 17:11
поделиться
  • Hashtable и ConcurrentHashMap не позволяют null ключи или null значения.

  • Collections.synchronizedMap(Map) синхронизируется весь операции (get, put, size, и т.д.).

  • ConcurrentHashMap поддержки полный параллелизм извлечений и корректируемый ожидаемый параллелизм для обновлений.

, Как обычно, существует параллелизм - наверху - включенные компромиссы скорости. Действительно необходимо полагать, что подробные требования параллелизма приложения принимают решение, и затем тестируют код, чтобы видеть, достаточно хорошо ли это.

12
ответ дан Zach Scrivena 6 September 2016 в 17:11
поделиться
  • 1
    спасибо, которое помогло мне после многих поисков решения. – etaiso 19 August 2013 в 01:23
Другие вопросы по тегам:

Похожие вопросы: