我试图编写一个单例类,它将用于简单的缓存实现。我按照双重检查锁定模式来获取实例是类中的volatile成员的实例。它还包含用于存储数据的 HashTable 。
如果我尝试通过某种方法访问地图中的值,我是否应该提供' synchronized'阻止并发访问的关键字?我问这个问题,因为在getInstance()方法中使用双重检查锁定,UserCache本身是同步
或者使用 ConcurrentHashMap 而不是 HashTable 更好吗?
有关详细信息,请参阅下面的代码段。
public class UserCache {
private volatile static UserCache instance;
private Hashtable<String, User> users = null;
private UserCache() {
this.users = new Hashtable<String, User>();
}
public static UserCache getInstance() {
if (instance == null) {
synchronized (UserCache.class) {
if (instance == null) {
instance = new UserCache();
}
}
}
return instance;
}
public synchronized User getUser(String userUid) {
return this.users.get(userUid);
}
public synchronized boolean addUser(User user) {
if (isValidUser(user.getUserUid())) {
return false;
}
this.users.put(user.getUserUid(), user);
return true;
}
...
非常感谢任何建议:)
提前致谢
答案 0 :(得分:0)
如果这是您的类的范围,那么ConcurrentHashMap将起作用。如果您有任何其他方法需要同步多个简单的get / put到地图,ReadWriteLock是允许并发读取的好选项。
使用volatile静态双重检查锁定的另一种替代方法是使用内部类:
private static final class DeferredLoader {
static final UserCache INSTANCE = new UserCache();
}
public static UserCache getInstance() {
return DeferredLoader.INSTANCE;
}
这具有不可变的优点,并且在第一次调用getInstance方法之前仍然推迟实例的创建。
答案 1 :(得分:0)
如果你的方法是同步的,我认为不需要ConcurrentHashMap。不过,我会使用Map&lt;,&gt;而不是Hashtable。赞成接口是一种很好的做法。