首先要了解下java1.6中的ConcurrentMap ,他是一个线程安全的Map实现,特别说明的是在没有特别需求的情况下可以用ConcurrentHashMap。我是想学习一下读写锁的应用,就自己实现了一个SimpleConcurrentHashMap.
package com.cttc.cache.entity;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class SimpleConcurrentMap<K, V> implements Map<K, V> {
final ReadWriteLock lock = new ReentrantReadWriteLock();
final Lock r = lock.readLock();
final Lock w = lock.writeLock();
final Map<K, V> map;
public SimpleConcurrentMap(Map<K, V> map) {
this.map = map;
if (map == null) throw new NullPointerException();
}
public void clear() {
w.lock();
try {
map.clear();
} finally {
w.unlock();
}
}
public boolean containsKey(Object key) {
r.lock();
try {
return map.containsKey(key);
} finally {
r.unlock();
}
}
public boolean containsValue(Object value) {
r.lock();
try {
return map.containsValue(value);
} finally {
r.unlock();
}
}
public Set<java.util.Map.Entry<K, V>> entrySet() {
throw new UnsupportedOperationException();
}
public V get(Object key) {
r.lock();
try {
return map.get(key);
} finally {
r.unlock();
}
}
public boolean isEmpty() {
r.lock();
try {
return map.isEmpty();
} finally {
r.unlock();
}
}
public Set<K> keySet() {
r.lock();
try {
return new HashSet<K>(map.keySet());
} finally {
r.unlock();
}
}
public V put(K key, V value) {
w.lock();
try {
return map.put(key, value);
} finally {
w.unlock();
}
}
public void putAll(Map<? extends K, ? extends V> m) {
w.lock();
try {
map.putAll(m);
} finally {
w.unlock();
}
}
public V remove(Object key) {
w.lock();
try {
return map.remove(key);
} finally {
w.unlock();
}
}
public int size() {
r.lock();
try {
return map.size();
} finally {
r.unlock();
}
}
public Collection<V> values() {
r.lock();
try {
return new ArrayList<V>(map.values());
} finally {
r.unlock();
}
}
}
缓存对象CacheEntity.java为:
package com.cttc.cache.entity;
import java.io.Serializable;
public class CacheEntity implements Serializable{
private static final long serialVersionUID = -3971709196436977492L;
private final int DEFUALT_VALIDITY_TIME = 20;//默认过期时间 20秒
private String cacheKey;
private Object cacheContext;
private int validityTime;//有效期时长,单位:秒
private long timeoutStamp;//过期时间戳
private CacheEntity(){
this.timeoutStamp = System.currentTimeMillis() + DEFUALT_VALIDITY_TIME * 1000;
this.validityTime = DEFUALT_VALIDITY_TIME;
}
public CacheEntity(String cacheKey, Object cacheContext){
this();
this.cacheKey = cacheKey;
this.cacheContext = cacheContext;
}
public CacheEntity(String cacheKey, Object cacheContext, long timeoutStamp){
this(cacheKey, cacheContext);
this.timeoutStamp = timeoutStamp;
}
public CacheEntity(String cacheKey, Object cacheContext, int validityTime){
this(cacheKey, cacheContext);
this.validityTime = validityTime;
this.timeoutStamp = System.currentTimeMillis() + validityTime * 1000;
}
public String getCacheKey() {
return cacheKey;
}
public void setCacheKey(String cacheKey) {
this.cacheKey = cacheKey;
}
public Object getCacheContext() {
return cacheContext;
}
public void setCacheContext(Object cacheContext) {
this.cacheContext = cacheContext;
}
public long getTimeoutStamp() {
return timeoutStamp;
}
public void setTimeoutStamp(long timeoutStamp) {
this.timeoutStamp = timeoutStamp;
}
public int getValidityTime() {
return validityTime;
}
public void setValidityTime(int validityTime) {
this.validityTime = validityTime;
}
}
List缓存处理对象:
[java] view plaincopyprint?
package com.cttc.cache.handler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.cttc.cache.entity.CacheEntity;
import com.cttc.cache.entity.SimpleConcurrentMap;
public class CacheListHandler {
private static final long SECOND_TIME = 1000;
private static final SimpleConcurrentMap<String, CacheEntity> map;
private static final List<CacheEntity> tempList;
static{
tempList = new ArrayList<CacheEntity>();
map = new SimpleConcurrentMap<String, CacheEntity>(new HashMap<String, CacheEntity>(1<<18));
new Thread(new TimeoutTimerThread()).start();
}
/**
* 增加缓存对象
* @param key
* @param ce
*/
public static void addCache(String key, CacheEntity ce){
addCache(key, ce, ce.getValidityTime());
}
/**
* 增加缓存对象
* @param key
* @param ce
* @param validityTime 有效时间
*/
public static synchronized void addCache(String key, CacheEntity ce, int validityTime){
ce.setTimeoutStamp(System.currentTimeMillis() + validityTime * SECOND_TIME);
map.put(key, ce);
//添加到过期处理队列
tempList.add(ce);
}
/**
* 获取缓存对象
* @param key
* @return
*/
public static synchronized CacheEntity getCache(String key){
return map.get(key);
}
/**
* 检查是否含有制定key的缓冲
* @param key
* @return
*/
public static synchronized boolean isConcurrent(String key){
return map.containsKey(key);
}
/**
* 删除缓存
* @param key
*/
public static synchronized void removeCache(String key){
map.remove(key);
}
/**
* 获取缓存大小
* @param key
*/
public static int getCacheSize(){
return map.size();
}
/**
* 清除全部缓存
*/
public static synchronized void clearCache(){
tempList.clear();
map.clear();
System.out.println("clear cache");
}
static class TimeoutTimerThread implements Runnable {
public void run(){
while(true){
try {
checkTime();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 过期缓存的具体处理方法
* @throws Exception
*/
private void checkTime() throws Exception{
//"开始处理过期 ";
CacheEntity tce = null;
long timoutTime = 1000L;
//" 过期队列大小 : "+tempList.size());
if(1 > tempList.size()){
System.out.println("过期队列空,开始轮询");
timoutTime = 1000L;
Thread.sleep(timoutTime);
return;
}
tce = tempList.get(0);
timoutTime = tce.getTimeoutStamp() - System.currentTimeMillis();
//" 过期时间 : "+timoutTime);
if(0 < timoutTime){
//设定过期时间
Thread.sleep(timoutTime);
return;
}
System.out.print(" 清除过期缓存 : "+tce.getCacheKey());
//清除过期缓存和删除对应的缓存队列
tempList.remove(tce);
removeCache(tce.getCacheKey());
}
}
}