谁能告诉我这个类是否是线程安全的?
class Foo {
private final Map<String,String> aMap;
public Foo() {
aMap = new HashMap<String, String>();
aMap.put("1", "a");
aMap.put("2", "b");
aMap.put("3", "c");
}
public String get(String key) {
return aMap.get(key);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:我不能澄清这个问题.根据JMM FAQ:
应提供初始化安全性的新保证.如果一个对象被正确构造(这意味着对它的引用在构造期间不会被转义),那么看到对该对象的引用的所有线程也将看到在构造函数中设置的最终字段的值,而不需要同步.
这让我把这个集合混淆为aMap aMap = new HashMap<String, String>();.所以其他线程可以看到这些
aMap.put("1", "a");
aMap.put("2", "b");
aMap.put("3", "c");
Run Code Online (Sandbox Code Playgroud)
或不 ?
编辑:我发现这个问题与我的问题完全不同
// Not really how java.util.concurrent.Semaphore is implemented
@ThreadSafe
public class SemaphoreOnLock {
private final Lock lock = new ReentrantLock();
// CONDITION PREDICATE: permitsAvailable (permits > 0)
private final Condition permitsAvailable = lock.newCondition();
@GuardedBy("lock") private int permits;
SemaphoreOnLock(int initialPermits) {
lock.lock();
try {
permits = initialPermits;
} finally {
lock.unlock();
}
}
/* other code omitted.... */
Run Code Online (Sandbox Code Playgroud)
我有一个关于上面的示例的问题,该示例是从Java Concurrency中提取的实践清单14.12计算使用Lock实现的信号量.
我想知道为什么我们需要在构造函数中获取锁(如图所示调用lock.lock()).据我所知,构造函数是原子的(除了引用转义),因为没有其他线程可以获得引用,因此,半构造对象对其他线程不可见.因此,我们不需要构造函数的synchronized修饰符.此外,只要对象安全发布,我们也不需要担心内存可见性.
那么,为什么我们需要在构造函数中获取ReentrantLock对象?