Хорошо, сначала об итерации чтения без блокировок. Это небезопасно, и вы не должны этого делать. Просто чтобы проиллюстрировать это самым простым способом - вы перебираете коллекцию, но никогда не знаете, сколько элементов в этой коллекции, и у вас нет возможности это выяснить. Где ты остановился? Проверка счетчика на каждой итерации не помогает, потому что он может измениться после того, как вы его проверите, но до того, как получите элемент.
ReaderWriterLock разработан для ситуации, когда вы разрешаете нескольким потокам иметь одновременный доступ на чтение, но принудительно выполняете синхронную запись. Судя по звукам вашего приложения, у вас нет нескольких одновременных считывателей, и записи столь же распространены, как и чтения, поэтому ReaderWriterLock не дает никаких преимуществ. В этом случае вам лучше обойтись классическим замком.
В целом, какие бы незначительные преимущества в производительности вы ни выдавали, не блокируя доступ к общим объектам с многопоточностью, они резко компенсируются случайными странностями и необъяснимым поведением. Заблокируйте все, что является общим, протестируйте приложение, а затем, когда все заработает, вы можете запустить на нем профилировщик, проверить, сколько времени приложение ожидает на блокировках, а затем, при необходимости, реализовать опасные хитрости. Но скорее всего, влияние будет небольшим.
«Мы должны забыть о малой эффективности, скажем, в 97% случаев: преждевременная оптимизация - корень всего зла. Тем не менее, мы не должны упускать наши возможности в эти критические 3%. Хорошие программисты не будут успокаиваться такими рассуждениями, он будет мудрым, чтобы внимательно посмотреть на критический код; но только после того, как этот код был идентифицирован » - Дональд Кнут