Нужен ли мне ConcurrentHashMap, если я вызываю только get, put, remove с ключом потока и никогда не повторяю карту? - PullRequest
0 голосов
/ 07 сентября 2018

Оригинальный вопрос здесь , но на этот раз немного другой сценарий.

У меня есть статический hashMap, который используется несколькими потоками. Я не повторяю карту и не беспокоюсь о размере карты. Я использую только get, put, remove на карте. Каждый поток может вызывать someClass.track(true) или someClass.track(false). Я хочу отслеживать, когда поток входит в метод (increment #) и выходить из метода (increments #) для каждого потока.

Достаточно ли использовать только HashMap? Или я должен использовать ConcurrentHashMap, чтобы гарантировать получение правильного значения из метода track?

Метод выглядит так

private static Map<Long, Integer> TRACKER = new HashMap<Long,Integer>();
public static Integer track(boolean b) {
    long tid = Thread.currentThread().getId();
    if (b) {
        if (TRACKER.containsKey(tid)) {
            TRACKER.put(tid, TRACKER.get(tid) + 1);
        } else {
            TRACKER.put(tid, 1);
        }
    } else {
        Integer n = TRACKER.get(tid);
        if (n != null) {
            n = n -1;
            if (n == 0) {
                TRACKER.remove(tid);
            } else {
                TRACKER.put(tid, n);
            }
        }
    }
    return TRACKER.get(tid);
  }

1 Ответ

0 голосов
/ 07 сентября 2018

Вы можете изменить карту во время чтения. Поэтому, по крайней мере, по этой причине вам следует рассмотреть возможность использования ConcurrentHashMap или использовать явный механизм синхронизации, так как HashMap не предназначен для использования таким образом:

Обратите внимание, что эта реализация не синхронизирована. Если несколько потоков получить доступ к хэш-карте одновременно и, по крайней мере, к одному из потоков изменяет карту структурно, она должна быть синхронизирована извне.

Или используйте ConcurrentHashMap.

Обратите внимание, что ConcurrentHashMap может не соответствовать, поскольку вы хотите получить значение, связанное с ключом, в определенный момент времени в соответствии с временной шкалой. Как и в ConcurrentHashMap, операции поиска не блокируются, они отражают последнюю «известную информацию», которая не обязательно является последней хронологической информацией :

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

Как правило, точная информация в момент I зависит от ваших требований. Вы не объясняете свой, но все равно, это не имеет значения, потому что в соответствии с вашим реальным кодом к методу одновременно обращаются потоки, которые не манипулируют одним и тем же ключом / значением. Итак, эта ConcurrentHashMap особенность не является проблемой.
Так что, похоже, очень хороший вариант использования для ConcurrentHashMap.

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