Является ли ConcurrentSkipListMap положил метод потокобезопасным?

Недавно во время изучения ConcurrentSkipListMap Я прошел его реализацию и обнаружил, что его метод put не является потокобезопасным. Это внутренне вызывает doPut который на самом деле добавляет элемент. Но я обнаружил, что этот метод не использует какой-либо вид блокировки, аналогичный ConcurrentHashMap,

Поэтому я хочу знать, add является потокобезопасным или нет. Глядя на метод, кажется, что он не является потокобезопасным - то есть, если этот метод выполняется двумя потоками одновременно, может возникнуть проблема.

я знаю ConcurrentSkipListMap внутренне использует структуру данных skiplist, но я ожидал add способ быть потокобезопасным. Я что-то не так понимаю? Является ConcurrentSkipListMap действительно не потокобезопасный?

3 ответа

Просто потому, что он не использует Lock не делает его небезопасным. Структура списка пропуска может быть реализована без блокировки.

Вы должны внимательно прочитать API.

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

Комментарии в реализации говорят:

Учитывая использование древовидных индексных узлов, вы можете удивиться, почему вместо этого не используется какое-то дерево поиска, которое будет поддерживать несколько более быстрые операции поиска. Причина в том, что не существует известных эффективных алгоритмов вставки и удаления без блокировок для деревьев поиска. Неизменность "нисходящих" связей узлов индекса (в отличие от изменяемых "левых" полей в истинных деревьях) делает это возможным, используя только операции CAS.

Поэтому они используют некоторые низкоуровневые функции программирования с операциями сравнения и замены, чтобы внести изменения в элементарную карту. При этом они обеспечивают безопасность потоков без необходимости синхронизировать доступ.

Вы можете прочитать это более подробно в исходном коде.

Мы должны доверять Java API. И вот что говорит документация пакета java.util.concurrent:

Параллельные Коллекции

Помимо очередей, этот пакет предоставляет реализации Collection, предназначенные для использования в многопоточных контекстах: ConcurrentHashMap, ConcurrentSkipListMap, ConcurrentSkipListSet, CopyOnWriteArrayList и CopyOnWriteArraySet.

Другие вопросы по тегам