【问题标题】:Variable concurrency in Singleton Class pattern单例类模式中的变量并发
【发布时间】:2014-06-12 12:17:22
【问题描述】:

我正在尝试编写一个单例类,它将用于简单的缓存实现。我遵循 双重检查锁定 模式来获取实例,其中实例是类中的 volatile 成员。它还包含一个 HashTable 用于存储数据。

如果我尝试通过方法访问映射内的值,是否应该提供“同步”关键字来阻止并发访问?我问这个问题是因为 UserCache 本身是 syncronized 在 getInstance() 方法中使用双重检查锁定

或者使用 ConcurrentHashMap 而不是 HashTable 更好?

查看下面的代码 sn-p 了解更多详情。

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;
}

...

任何建议将不胜感激:)

提前致谢

【问题讨论】:

  • 最好使用并发哈希映射,因为同步对您没有多大帮助。
  • 感谢您的建议@RomanC​​pan>

标签: java singleton hashtable synchronized concurrenthashmap


【解决方案1】:

如果这是你的类的范围,那么 ConcurrentHashMap 就可以了。如果您有任何其他方法需要同步的不仅仅是简单的 get/put 到 map,ReadWriteLock 是允许并发读取的好选择。

使用 volatile 静态双重检查锁定的另一种替代方法是使用内部类:

private static final class DeferredLoader {
    static final UserCache INSTANCE = new UserCache();
}

public static UserCache getInstance() {
    return DeferredLoader.INSTANCE;
}

这具有不可变的优点,并且仍然会延迟实例的创建,直到第一次调用 getInstance 方法。

【讨论】:

  • 感谢您的建议@Brett Okken。我将使用并发 hashmap
【解决方案2】:

如果您的方法是同步的,我认为不需要 ConcurrentHashMap。不过,我会使用 Map 而不是 Hashtable。支持接口是一种很好的做法。

【讨论】:

    猜你喜欢
    • 2010-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    相关资源
    最近更新 更多