Использование synchronizedSet для синхронизации доступа между двумя потоками - PullRequest
3 голосов
/ 22 октября 2011

Я не могу синхронизировать два потока, используя набор:

private Set<String> set;
...
set = Collections.synchronizedSet(new HashSet<String>());

и передача его в два потока. Один доступ:

synchronized (set) {
    // [1]
    if (set.contains(str)) {
    ...
    } else {
        // [3]
    }
}

и другое обновление:

synchronized (set) {
    set.add(str);   // [2]
...
}

Что происходит, так это то, что [1], [2], [3] происходит последовательно. Во время [1] правильно, что в наборе еще нет предмета, который я ищу. Но затем [2] обновляет его, добавляя элемент. А во время [3] я сейчас вижу предмет. Как это исправить? У меня также есть ConcurrentHashMap, совместно используемый теми же потоками, но он прекрасно работает. Что такое набор, эквивалентный ConcurrentHashMAp?

ОБНОВЛЕНИЕ: код слишком длинный. В любом случае, мой обновленный вопрос - что такое набор, эквивалентный ConcurrentHAshMap?

1 Ответ

6 голосов
/ 22 октября 2011

Вы правильно синхронизируете доступ.На самом деле, упаковка в synchronizedSet() не имеет здесь никакого дополнительного эффекта.Нет ConcurrentHashSet, хотя вы можете получить то же самое от Collections.newSetFromMap() и ConcurrentHashMap.Но это не проблема.

Проблема в другом месте вашего кода.Например: вы уверены, что синхронизируете на одном устройстве?Ваши ключи правильно реализуют hashCode() и equals()?Вы сделали их изменяемыми (плохая идея), и что-то меняет ключи?

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