Если у вас есть очередь / FIFO с несколькими производителями / одним потребителем, вы можете легко сделать одну LockFree с помощью SLIST или тривиального стека Lock Free LIFO. У вас есть второй «частный» стек для потребителя (который также может быть реализован в виде SLIST для простоты или любой другой модели стека по вашему выбору). Потребитель извлекает элементы из частного стека. Всякий раз, когда частный LIFO исчерпывается, вы выполняете Flush, а не Pop из совместно используемого параллельного SLIST (захват всей цепочки SLIST), а затем проходите по списку Flushing по порядку, помещая элементы в частный стек.
Это работает для одного производителя / одного потребителя и для нескольких производителей / одного потребителя.
Однако это не работает для случаев с несколькими потребителями (с одним или несколькими производителями).
Кроме того, что касается хеш-таблиц, они являются идеальным кандидатом для «чередования», при котором хеш просто разделяется на сегменты, имеющие блокировку на сегменты кеша. Вот как это делает параллельная библиотека Java (с использованием 32 полос). Если у вас есть облегченная блокировка чтения-записи, к хэш-таблице можно получить одновременный доступ для одновременного чтения, и вы остановитесь только тогда, когда запись происходит на оспариваемых полосах (и, возможно, если вы разрешите увеличение хеш-таблицы).
Если вы свертываете свои собственные, убедитесь, что ваши блокировки чередуются с записями хэша, а не помещают все свои блокировки в массив рядом друг с другом, чтобы у вас меньше шансов получить ложное совместное использование.