В основном это зависит от шаблона, который вам нужно использовать.
Если у вас есть несколько потоков, пишущих и читающих одно и то же место, вы можете использовать ту же структуру данных, которую вы использовали бы с одним потоком (hastable, array и т. Д.) С блокировкой / монитором или ReaderWriterLock, чтобы предотвратить состояние гонки.
В случае, если вам нужно передать данные между потоками, вам понадобится какая-то очередь (синхронизированная или без блокировки), в которую поток (ы) группы A будет вставлять, а поток (ы) группы B будет удалять из нее. Возможно, вы захотите использовать WaitEvent (AutoReset или Manual), чтобы не потерять процессор, когда очередь пуста.
Это действительно зависит от того, какой рабочий процесс вы хотите достичь.