Assuming we had this class
final class Foo {
private final Set bar = new HashSet<>();
public Foo() {
bar.add(\"one\");
Your Foo
and bar
are actually immutable. it is thread-safe.
It is thread safe provided that
1) The constructor does not leak a reference before its fully constructed.
2) No one has any way to access the collection.
3) No subclass can be created which can edit the collection.
As a general rule though, if you want to implement this use an immutable collection from guava, that makes the behaviour explicit to the programmer, and it is then safe to return the whole map. I think that in pure java you can return an unmodifiable view of a collection.
As long as this is accessed in a read only manner I think you should be safe. Also , java offers immutable versions of it's base collections exposed through static methods on the Collections class , so I would look at Collections.unmodifiableSet()
.
Also , while you add strings in your example, and strings themselves are immutable in java , you would be in trouble if you added mutable objects and then decided to modify/read them from different threads (you would need synchronized blocks in this case).
It depends on how the access to this object is published. While the bar
Set
is final and thus guaranteed to visible to all threads, the population of the map is not guaranteed to happen before the conclusion of constructor.
This, however would be guaranteed to be thread safe regardless of how the object was created and made available.
private final Set<String> bar;
public Foo() {
bar = new HashSet<String>(Arrays.asList("one", "two", "three"));
}
Testing initialization safety of final fields
https://stackoverflow.com/a/23995782/676877