java应用集锦5:缓存管理 单例模式 ThreadLocal

阅读更多

转载请注明出处: http://renjie120.iteye.com/

 

在项目中经常需要使用缓存下拉菜单的值,可以使用一个map进行缓存管理;单例模式在项目中经常要使用,是很有用的一个设计模式;ThreadLocal在自己的一个框架中使用了,其本身也是被spring框架所使用来管理例如事务等,很有用的一个java类!

1.提供一个改造的简单的缓存管理类CacheManager

2.单例模式的简单实现

3.ThreadLocal的使用举例

1.CacheManager类,从名字看是管理Cache的管理器,主要有两个类:

package com.lsframe.cache;


public class Cache {
	private String key;// 缓存ID
	private Object value;// 缓存数据
	private long timeOut;// 更新时间
	private boolean expired; // 是否终止

	public Cache() {
		super();
	}

	public Cache(String key, Object value, long timeOut, boolean expired) {
		this.key = key;
		this.value = value;
		this.timeOut = timeOut;
		this.expired = expired;
	}

	public String getKey() {
		return key;
	}

	public long getTimeOut() {
		return timeOut;
	}

	public Object getValue() {
		return value;
	}

	public void setKey(String string) {
		key = string;
	}

	public void setTimeOut(long l) {
		timeOut = l;
	}

	public void setValue(Object object) {
		value = object;
	}

	public boolean isExpired() {
		return expired;
	}

	public void setExpired(boolean b) {
		expired = b;
	}
}

 

package com.lsframe.cache;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

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

	// 单实例构造方法
	private CacheManager() {
		super();
	}

	// 获取布尔值的缓存
	public static boolean getSimpleFlag(String key) {
		try {
			return (Boolean) cacheMap.get(key);
		} catch (NullPointerException e) {
			return false;
		}
	}

	public static long getServerStartdt(String key) {
		try {
			return (Long) cacheMap.get(key);
		} catch (Exception ex) {
			return 0;
		}
	}

	// 设置布尔值的缓存
	public synchronized static boolean setSimpleFlag(String key, boolean flag) {
		if (flag && getSimpleFlag(key)) {// 假如为真不允许被覆盖
			return false;
		} else {
			cacheMap.put(key, flag);
			return true;
		}
	}

	public synchronized static boolean setSimpleFlag(String key,
			long serverbegrundt) {
		if (cacheMap.get(key) == null) {
			cacheMap.put(key, serverbegrundt);
			return true;
		} else {
			return false;
		}
	}

	// 得到缓存。同步静态方法
	private synchronized static Cache getCache(String key) {
		return (Cache) cacheMap.get(key);
	}

	// 判断是否存在一个缓存
	private synchronized static boolean hasCache(String key) {
		return cacheMap.containsKey(key);
	}

	// 清除所有缓存
	public synchronized static void clearAll() {
		cacheMap.clear();
	}

	// 清除某一类特定缓存,通过遍历HASHMAP下的所有对象,来判断它的KEY与传入的TYPE是否匹配
	public synchronized static void clearAll(String type) {
		Iterator i = cacheMap.entrySet().iterator();
		String key;
		ArrayList arr = new ArrayList();
		try {
			while (i.hasNext()) {
				java.util.Map.Entry entry = (java.util.Map.Entry) i.next();
				key = (String) entry.getKey();
				if (key.startsWith(type)) { // 如果匹配则删除掉
					arr.add(key);
				}
			}
			for (int k = 0; k < arr.size(); k++) {
				clearOnly(arr.get(k));
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	// 清除指定的缓存
	public synchronized static void clearOnly(String key) {
		cacheMap.remove(key);
	}

	// 载入缓存
	public synchronized static void putCache(String key, Cache obj) {
		cacheMap.put(key, obj);
	}

	/**
	 * 获取缓存信息.
	 * @param key
	 * @return
	 */
	public static Cache getCacheInfo(String key) {
		if (hasCache(key)) {
			Cache cache = getCache(key);
			if (cacheExpired(cache)) { // 调用判断是否终止方法
				cache.setExpired(true);
			}
			return cache;
		} else
			return null;
	}

	/**
	 * 载入缓存信息.
	 * @param key
	 * @param obj
	 * @param dt
	 * @param expired
	 */
	public static void putCacheInfo(String key, Cache obj, long dt,
			boolean expired) {
		Cache cache = new Cache();
		cache.setKey(key);
		cache.setTimeOut(dt + System.currentTimeMillis()); // 设置多久后更新缓存
		cache.setValue(obj);
		cache.setExpired(expired); // 缓存默认载入时,终止状态为FALSE
		cacheMap.put(key, cache);
	}

	/**
	 * 重写载入缓存信息方法.
	 * @param key
	 * @param obj
	 * @param dt
	 */
	public static void putCacheInfo(String key, Cache obj, long dt) {
		Cache cache = new Cache();
		cache.setKey(key);
		cache.setTimeOut(dt + System.currentTimeMillis());
		cache.setValue(obj);
		cache.setExpired(false);
		cacheMap.put(key, cache);
	}
	
	/**	
	 * 判断缓存是否终止.
	 * @param cache
	 * @return
	 */
	public static boolean cacheExpired(Cache cache) {
		if (null == cache) { // 传入的缓存不存在
			return false;
		}
		long nowDt = System.currentTimeMillis(); // 系统当前的毫秒数
		long cacheDt = cache.getTimeOut(); // 缓存内的过期毫秒数
		if (cacheDt <= 0 || cacheDt > nowDt) { // 过期时间小于等于零时,或者过期时间大于当前时间时,则为FALSE
			return false;
		} else { // 大于过期时间 即过期
			return true;
		}
	}

	/**
	 * 获取缓存中的大小.
	 * @return
	 */
	public static int getCacheSize() {
		return cacheMap.size();
	}

	/**
	 * 获取指定的类型的大小
	 * @param type
	 * @return
	 */
	public static int getCacheSize(String type) {
		int k = 0;
		Iterator i = cacheMap.entrySet().iterator();
		String key;
		try {
			while (i.hasNext()) {
				java.util.Map.Entry entry = (java.util.Map.Entry) i.next();
				key = (String) entry.getKey();
				if (key.indexOf(type) != -1) { // 如果匹配则删除掉
					k++;
				}
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return k;
	}

	/**
	 * 获取缓存对象中的所有键值名称.
	 * @return
	 */
	public static ArrayList getCacheAllkey() {
		ArrayList a = new ArrayList();
		try {
			Iterator i = cacheMap.entrySet().iterator();
			while (i.hasNext()) {
				java.util.Map.Entry entry = (java.util.Map.Entry) i.next();
				a.add((String) entry.getKey());
			}
		} catch (Exception ex) {
		} finally {
			return a;
		}
	}

	/**
	 * 获取缓存对象中指定类型的键值名称.
	 * @param type
	 * @return
	 */
	public static ArrayList getCacheListkey(String type) {
		ArrayList a = new ArrayList();
		String key;
		try {
			Iterator i = cacheMap.entrySet().iterator();
			while (i.hasNext()) {
				java.util.Map.Entry entry = (java.util.Map.Entry) i.next();
				key = (String) entry.getKey();
				if (key.indexOf(type) != -1) {
					a.add(key);
				}
			}
		} catch (Exception ex) {
		} finally {
			return a;
		}
	}
}

 

使用举例:

public List getAllTallyTypes(){
		List allTallyTypes = null;
		TallyTypeDao tallyTypeDao = new TallyTypeDao();
		//从缓存中取列表,对于这里类似是取字典表的数据,所以可以使用缓存。
		if(CacheManager.getCacheInfo("tallyTypes")==null){
			allTallyTypes = tallyTypeDao.doGetAllTallyTypes(
				"from tallyBook.pojo.TallyType");
			Cache c = new Cache();
			c.setKey("tallyTypes");
			c.setValue(allTallyTypes);
			CacheManager.putCache("tallyTypes",c);
		}else{
			allTallyTypes = (List)CacheManager.getCacheInfo("tallyTypes").getValue();
		}
		return allTallyTypes;
	}

 

2.关于单例类的举例,截取代码自改造的一个简单的数据库连接池代码:

public class DBPoolManager {
/**
	 * 返回连接池管理对象的实例
	 * @return
	 */
	public static DBPoolManager getInstance() {
		if(dbManager==null){
			dbManager = new DBPoolManager();
		}
		//创建了一次就计数累加一次。
		clientCount++;
		return dbManager;
	}
     private DBPoolManager() {
		//构造函数中进行初始化操作
		init();
	}

	private void init() {
		try {
			pros = new Properties();
			pros.load(this.getClass().getResourceAsStream("/db.properties"));
		} catch (Exception ex) {
			log.error("没有找到连接池配置文件", ex);
		}
		loadDriver();
		createPool();
	}
}

 

单例模式的典型特征之一,就是私有的构造函数!然后有一个init()这样的方法返回对象的实例.

3.使用本地线程变量的实例,代码来自改造的一个MVC框架片段,用于设置了request变量之后,再方便取出request变量:

package com.lsframe.mvc;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ActionContext {
	private static ThreadLocal actionContext = new ThreadLocal();

	/**
	 * 取得上下文的内容.
	 * @return
	 */
	public static ActionContext getContext() {
		return (ActionContext) actionContext.get();
	}

	/**
	 * 设置上下文.
	 * @param context
	 */
	public static void setContext(ActionContext context) {
		actionContext.set(context);
	}

	private Map context = null;

	/**
	 * 初始化上下文环境.
	 * @param context
	 */
	public ActionContext(Map context) {
		this.context = context;
	}

	/**
	 * 得到上下文.
	 * @return
	 */
	public Map getContextMap() {
		return context;
	}

	/**
	 * 取得上下文中的值.
	 * @param key
	 * @return
	 */
	public Object get(String key) {
		return context.get(key);
	}

	/**
	 * 取得上下文中的HttpServletRequest对象.
	 * @return
	 */
	public HttpServletRequest getHttpServletRequest() {
		return (HttpServletRequest) context.get("HttpServletRequest");
	}

	/**
	 * 取得上下文中的HttpServletResponse.
	 * @return
	 */
	public HttpServletResponse getHttpServletResponse() {
		return (HttpServletResponse) context.get("HttpServletResponse");
	}
}

 设置request的时候,只需要使用:

 

Map context = new HashMap();
   context.put("HttpServletRequest", request);
   context.put("HttpServletResponse", response);
   ActionContext actionContext = new ActionContext(context);
   ActionContext.setContext(actionContext);

 如此简单!!多谢这个方便的本地线程变量,然后就可以在一个请求的任意位置得到request了...是不是和session很相似的机制,好像session就是用这个实现的...

 

你可能感兴趣的:(Java,配置管理,设计模式,项目管理,Cache)