加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 加载静态缓存的最佳模式或方法是什么?

发布时间:2020-12-15 08:30:15 所属栏目:Java 来源:网络整理
导读:假设我有以下内容(假设仅限于 java 1.4,因此没有泛型): public class CacheManager { static HashMap states; static boolean statesLoaded; public static String getState(String abbrev) { if(!statesLoaded) { loadStates(); } return (String) states.
假设我有以下内容(假设仅限于 java 1.4,因此没有泛型):

public class CacheManager {
    static HashMap states;
    static boolean statesLoaded;

    public static String getState(String abbrev) {
        if(!statesLoaded) {
            loadStates();
        }
        return (String) states.get(abbrev);
    }

    private static void loadStates() {
        //JDBC stuff to load the data
        statesLoaded = true;
    }
}

在像Web应用服务器这样的高负载多线程环境中,如果>这在理论上可能存在问题. 1个线程尝试同时获取并加载缓存. (进一步假设Web应用程序上没有用于初始化缓存的启动代码)

只是使用Collections.synchronizedMap足以解决这个问题吗?如果很多线程正在访问它,那么在执行get()时返回的synchronizedMap是否存在性能问题?

或者更好的是拥有一个非同步的HashMap,而是在load方法或boolean变量上同步?我认为如果你同步其中任何一个,你可能会最终锁定该类.

例如,如果load方法已同步,那么如果两个线程同时进入getStates()方法,并且两者都看到statesLoaded为false.第一个获取方法的锁定,加载缓存并将statesLoaded设置为true.不幸的是,第二个线程已经评估了statesLoaded为false,并且一旦锁定空闲就进入load方法.它不会继续并再次加载缓存吗?

解决方法

在这种情况下加载缓存的最佳方法是利用JVM静态初始化:

public class CacheManager {
    private static final HashMap states = new HashMap();

    public static String getState(String abbrev) {
        return (String) states.get(abbrev);
    }

    static {
        //JDBC stuff to load the data
    }
}

缓存将在第一次使用类时加载,并且由于静态初始化是线程安全的,因此将安全地填充映射.任何后续调用来检索值都可以在不涉及任何锁定的情况下完成.

尽可能利用静态初始化始终是个好主意.它安全,高效,而且通常非常简单.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读