Поскольку я сам был несколько смущен, я начну с разъяснения нескольких понятий в этом вопросе.
Коллекция . Я не вижу смысла тратить время на строгое определение того, что означает «сбор», когда мы можем просто спросить, что происходит со структурами данных в целом. Структура данных занимает часть памяти и имеет некоторые операции, которые могут обращаться к этой памяти и которые могут вызываться пользователями . Эти пользователи могут быть разными процессорами или просто разными потоками, нас это не касается. Важно только то, что они могут выполнять операции параллельно.
Без блокировки . Херлихи и Босс говорят, что структура данных не блокируется, когда сбойный пользователь не препятствует дальнейшему использованию структуры данных. Например, представьте, что вы льете воду на процессор, который находится в процессе вставки узла в отсортированный набор. Что ж, если другие процессоры позже попытаются вставить в этот отсортированный набор, они должны преуспеть. ( Редактировать: в соответствии с этим определением, это случай, когда структура данных использует блокировки, тогда она не свободна от блокировки, но это не тот случай, когда структура данных не использует блокировки, то она не блокируется.)
С этим определением, я думаю, что Херлихи и Босс в основном говорят, что ответ - превратить критические регионы в транзакции.
Но вы можете спросить, имеет ли это такую же сложность? Я не уверен, что вопрос имеет смысл. Посмотрим push(x) { lock(); stack[size++] = x; unlock(); }
. Это операция с постоянным временем? Если вы игнорируете операцию блокировки и, следовательно, других пользователей, вы можете ответить ДА. Если вы не хотите игнорировать других пользователей, то на самом деле нет никакого способа сказать, будет ли push выполняться в постоянное время. Если вы поднимитесь на один уровень вверх и увидите, как стек используется каким-то конкретным алгоритмом, вы можете сказать, что push всегда будет занимать постоянное время (измеряется сейчас с точки зрения того, что происходит с входом вашего параллельного алгоритма). Но это действительно свойство вашего алгоритма, поэтому не имеет смысла говорить, что push - это операция с постоянным временем.
Таким образом, если вы игнорируете, сколько пользователь, выполняющий операцию, ожидает других пользователей, то использование транзакций вместо критических областей отвечает на ваш вопрос утвердительно. Если вы не игнорируете время ожидания, вам нужно посмотреть, как используется структура данных.