Да, это так. Пока строительство объекта HashSet
является потокобезопасным, доступ к нему всегда будет безопасным потоком, пока содержимое не изменится.
Если вы initialize в Lazy
с помощью LazyThreadSafetyMode.PublicationOnly
вы можете быть уверены, что инициализация Lazy
является поточно.
Когда несколько потоков пытаются инициализировать экземпляр Lazy<T>
одновременно, все потоки могут выполняться методом инициализации (или конструктор по умолчанию, если не существует метод инициализации). Первый поток для завершения инициализации задает значение экземпляра Lazy<T>
. Это значение возвращается к любым другим потокам, которые одновременно запускали метод инициализации, если только метод инициализации не генерирует исключения из этих потоков.
Небольшой пример кода:
var l = new Lazy<HashSet<string>>(() => new HashSet<string>() { "a" }
, LazyThreadSafetyMode.PublicationOnly
);
Да еще раз, если он действительно не меняется, в то время как строится не доступен, то да вам будет хорошо. Тем не менее, нет ничего, что помешало бы кому-то изменить его, поэтому его «чистое» поведение неукреплено. Попробуйте неизменные коллекции. –
@AdamHouldsworth, к сожалению, неизменные коллекции имеют ужасающую производительность http://ayende.com/blog/164739/immutable-collections-performance –
@ChrisMarisic Плохая производительность довольно известна. При этом для многих сценариев проблемы с производительностью не будут возникать. Вы всегда можете реализовать свою собственную, обернув внутри себя неизменяемые коллекции, которые на протяжении многих лет применяли к ним много оптимизаций. –