假设我们有这个班级
final class Foo {
private final Set<String> bar = new HashSet<>();
public Foo() {
bar.add("one");
bar.add("two");
bar.add("three");
}
public boolean contains(final String s) {
return bar.contains(s);
}
}
从多个线程实例化Foo
并调用此对象的contains
是不是线程安全?
private
和final
。没有人可以直接访问该系列。如果没有,是否有一个纯Java替代Guava的不可变集合?
答案 0 :(得分:2)
您的Foo
和bar
实际上是不可变的。它是线程安全的。
答案 1 :(得分:1)
这取决于如何发布对此对象的访问权限。虽然bar
Set
是最终的,因此保证所有线程都可见,但是在构造函数结束之前不能保证映射的数量。
但无论对象是如何创建并可用的,都可以保证线程安全。
private final Set<String> bar;
public Foo() {
bar = new HashSet<String>(Arrays.asList("one", "two", "three"));
}
答案 2 :(得分:0)
只要以只读方式访问,我认为您应该是安全的。此外,java提供了通过Collections类上的静态方法公开的基础集合的不可变版本,因此我将查看Collections.unmodifiableSet()
。
此外,当您在示例中添加字符串,并且字符串本身在java中是不可变的时,如果添加了可变对象然后决定从不同的线程修改/读取它们,则会遇到麻烦(在此需要同步块)案件)。
答案 3 :(得分:0)
提供线程安全
1)构造函数在完全构造之前不会泄漏引用。
2)没有人有办法访问该系列。
3)不能创建可以编辑集合的子类。
作为一般规则,如果你想实现这个使用来自guava的不可变集合,那么这个行为对程序员来说是显而易见的,然后返回整个映射是安全的。我认为在纯java中你可以返回一个不可修改的集合视图。