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.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 } } 缓存将在第一次使用类时加载,并且由于静态初始化是线程安全的,因此将安全地填充映射.任何后续调用来检索值都可以在不涉及任何锁定的情况下完成. 尽可能利用静态初始化始终是个好主意.它安全,高效,而且通常非常简单. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |