Java中缓存机制

缓存在很多地方我们都能看见,从数据库,hibernate(数据访问层),web前端都存在缓存问题.其中利弊我就不争论了,只是在上次的面试中,遇到一个实例.在一个项目中会存在大量的查询操作,有什么办法能更好的解决.我想缓存机制或许可以运用到.
下面大概写一下java的缓存机制吧,一个简单的缓存实例,方便以后在实际需求中进一步的改进.
Cache对象类
package cn.iholdmika.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 void setKey(String key) {
this.key = key;
}

public Object getValue() {
return value;
}

public void setValue(Object value) {
this.value = value;
}

public long getTimeOut() {
return timeOut;
}

public void setTimeOut(long timeOut) {
this.timeOut = timeOut;
}

public boolean isExpired() {
return expired;
}

public void setExpired(boolean expired) {
this.expired = expired;
}

}

缓存管理类
package cn.iholdmika.cache;

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

public class CacheManager {

private static HashMap<String, Object> cacheMap = new HashMap<String, Object>();

// 单例模式
private CacheManager() {
super();
}

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

// 获取long型缓存
public static long getServerStartdt(String key) {
try {
return (long) cacheMap.get(key);
} catch (Exception e) {
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 iterator = cacheMap.entrySet().iterator();
String key;
ArrayList<String> arr = new ArrayList<String>();
try {
while (iterator.hasNext()) {
java.util.Map.Entry<String, Object> entry = (Entry<String, Object>) iterator
.next();
key = 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);
}

// 获取缓存信息

public static Cache getCacheInfo(String key) {

if (hasCache(key)) {
Cache cache = getCache(key);
if (cacheExpired(cache)) { // 调用判断是否终止方法
cache.setExpired(true);
}
return cache;
} else
return null;
}

// 载入缓存信息
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);

}

// 重写载入缓存信息方法
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);

}

// 判断缓存是否终止
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;
}
}

// 获取缓存中的大小

public static int getCacheSize() {
return cacheMap.size();
}

// 获取指定的类型的大小
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;
}

// 获取缓存对象中的所有键值名称
public static ArrayList<String> 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;
}
}

// 获取缓存对象中指定类型 的键值名称
public static ArrayList<String> 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;
}
}
}

另一种考虑多线程的Cache
package cn.iholdmika.cache01;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteLockDemo {
static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

public static void main(String[] args) {
Data data = new Data();
Worker t1 = new Worker(data, true);
Worker t2 = new Worker(data, true);
t1.start();
t2.start();
}

static class Worker extends Thread {
Data data;
boolean read;

public Worker(Data data, boolean read) {
this.data = data;
this.read = read;
}

public void run() {
if (read)
data.get();
else
data.set();
}
}

static class Data {
//ReadWriteLock 可以实现在对加锁后的对象进行 ' 写 ' 操作的时,其他线程不能读写,而在 ' 读 ' 操作时其他线程则可以 ' 读而不可以写'.
ReadWriteLock lock = new ReentrantReadWriteLock();
Lock read = lock.readLock();
Lock write = lock.writeLock();

public void set() {
write.lock();
System.out.println(Thread.currentThread().hashCode()
+ " set:begin " + sdf.format(new Date()));
try {
Thread.sleep(5000);
//
} catch (Exception e) {

} finally {
System.out.println(Thread.currentThread().hashCode()
+ " set:end " + sdf.format(new Date()));
write.unlock();
}

}

public int get() {
read.lock();
System.out.println(Thread.currentThread().hashCode()
+ " get :begin " + sdf.format(new Date()));
try {
Thread.sleep(5000);
} catch (Exception e) {

} finally {
System.out.println(Thread.currentThread().hashCode()
+ " get :end " + sdf.format(new Date()));
read.unlock();
}

return 1;
}
}
}

这都是借鉴别人的代码,我自己重新写了一次,并自己理解.纯粹自己使用...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值