Обычно вы используете реализацию Set , и чаще всего HashSet. Если вам действительно нужен параллельный доступ, то ConcurrentHashSet предоставляет замену, которая обеспечивает безопасный параллельный доступ, включая безопасную итерацию по набору.
Я бы порекомендовал в любом случае ссылаться на него как на просто Set во всем вашем коде, за исключением одного места, где вы его создаете; таким образом, проще внедрить одну реализацию для другой, если позже она понадобится.
Даже если набор доступен только для чтения , если он используется потоком, отличным от того, который его создает, вам нужно подумать о safe публикации (то есть, чтобы убедиться, что любой другой поток видит набор в непротиворечивом состоянии: помните, что любые записи в память, даже в конструкторы, не гарантированно будут доступны другим потокам, когда вы ожидаете или в другом порядке, если вы принять меры для обеспечения этого). Это можно сделать одним из следующих способов:
- убедившись, что единственная ссылка (и) на набор находится в конечных полях ;
- убедившись, что действительно верно, что ни один поток не изменяет набор.
Вы можете помочь в этом, используя оболочку Collections.unmodifiableSet (). Это дает вам неизменяемое представление данного набора - так что при отсутствии других «нормальных» ссылок на наборы вы можете быть в безопасности.