当柳上原的风吹向天际的时候...

真正的快乐来源于创造

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  368 Posts :: 1 Stories :: 201 Comments :: 0 Trackbacks
Cache的作用:
在并发环境中减少重复性的对后台的调用,从而提高运行效率。

Cache必须要做到的:
1.保证Cache中的数据与后台系统数据的一致性。
2.Cache必须要减少访问后台的操作以提高效率。
如果不能同时做到以上两点,则Cache失去了意义。

Cache的基本操作:
Read(Get):按键值从Cache中取得想要的数据;
Write(Put):将键值对放到Cache中;
Reset(RemoveAll):清除Cache中的原有数据;
IsExist(has):判断某键在Cache中是否存在。

Cache中对数据的保护:
因为Cache多用于多线程环境中,需要对数据进行保护;
同步方法,同步块能起到保护的作用,但是效率不高;
读写锁也能起到保护的左右,而且效率较高。

Cache数据的时效性:
使用过期数据是危险的,我们必须确保取出的数据的时效性;
当放入数据时我们可以记录放入的时间,这样取出时就能得到它,然后与当前时间进行比较,如果小于一定间隔则可以认为数据没有时效。间隔一般可以设置为后台数据被更新间隔的平均时间的一半。

Cache的设计:
1.Data类,用以存储数据和放入时间:
import java.io.Serializable;
import java.util.Date;

public class Data implements Serializable{
    
private static final long serialVersionUID = 8596587790584575734L;
    
    
private byte[] value;

    
private Date date;
    
    
public Data(byte[] value,Date date){
        
this.value=value;
        
this.date=date;
    }
    
    
public byte[] getValue() {
        
return value;
    }

    
public void setValue(byte[] value) {
        
this.value = value;
    }

    
public Date getDate() {
        
return date;
    }

    
public void setDate(Date date) {
        
this.date = date;
    }
}

2.ReadWriteLock,用以在并发环境中保护数据:
/**
 * Read-write Lock Class
 * 
 * 
@author heyang
 * @time Sep 23, 2011,3:55:55 PM
 
*/
public class ReadWriteLock {
    
private boolean isRead;
    
private boolean isWrite;
    
    
/**
     * Add Read Lock
     
*/
    
public synchronized void readLock(){
        
while(isWrite){
            
try{    
                wait();
            }
            
catch(InterruptedException ex){
                ex.printStackTrace();
            }
        }
        
        isRead
=true;
    }
    
    
/**
     * Unlock the read-lock
     
*/
    
public synchronized void readUnlock(){
        isRead
=false;
        notifyAll();
    }
    
    
/**
     * Add write lock
     
*/
    
public synchronized void writeLock(){
        
while(isRead){
            
try{    
                wait();
            }
            
catch(InterruptedException ex){
                ex.printStackTrace();
            }
        }
        
        
while(isWrite){
            
try{    
                wait();
            }
            
catch(InterruptedException ex){
                ex.printStackTrace();
            }
        }
        
        isWrite
=true;
    }
    
    
/**
     * Unlock the write-lock
     
*/
    
public synchronized void writeUnlock(){
        isWrite
=false;
        notifyAll();
    }
}

3.AbstractCacheMap,用以提供Cache的接口和操作:
import java.util.Date;


/**
 * Parent class of InnerCacheMap & OutterCacheMap
 * 
 * 
@author heyang
 * @time Sep 23, 2011,4:00:45 PM
 
*/
public abstract class AbstractCacheMap {
    
private static final int Time_Limit_300 = 300;
    
    
// Read-Write lock,for protecting the cacheMap in the Multi-thread environment
    private ReadWriteLock lock;
    
    
/**
     * Contructor
     
*/
    
public AbstractCacheMap() {
        lock 
= new ReadWriteLock();
    }
    
    
/**
     * Put key-value pair into cacheMap
     * It can be called by any class
     * 
@param key
     * 
@param value
     * 
@throws Exception
     
*/
    
public void writeData(String key,byte[] value) throws Exception{
        
try {
            lock.writeLock();
            set(key,
new Data(value,new Date()));
        } 
finally {
            lock.writeUnlock();
        }
    }
    
    
/**
     * Put key-value pair into cacheMap,force child-class to implement.
     * It only can be called by child-class
     * 
@param key
     * 
@param value
     
*/
    
protected abstract void set(String key,Data data) throws Exception;

    
/**
     * Get value by it's key
     * It can be called by any class
     * 
     * 
@param key
     * 
@return
     * 
@throws Exception
     
*/
    
public byte[] readData(String key) throws Exception{
        
try {
            lock.readLock();
            Data data
=get(key);
            
return data.getValue();
        } 
finally {
            lock.readUnlock();
        }
    }
    
    
/**
     * Get value by it's key,force child-class to implement.
     * It only can be called by child-class
     * 
     * 
@param key
     * 
@return
     * 
@throws Exception
     
*/
    
protected abstract Data get(String key) throws Exception;
    
    
/**
     * Judge the existence of a key
     * It can be called by any class
     * 
     * 
@param key
     * 
@return
     * 
@throws Exception
     
*/
    
public boolean containsKey(String key) throws Exception{
        
try {
            lock.readLock();
            
            
if(contains(key)){
                Data data
=get(key);
                
                
return isexceedTimeLimit(data.getDate());
            }
            
return false;
        } 
finally {
            lock.readUnlock();
        }
    }
    
    
/**
     * Judge the existence of a key,force child-class to implement.
     * It only can be called by child-class
     * 
     * 
@param key
     * 
@return
     * 
@throws Exception
     
*/
    
protected abstract boolean contains(String key) throws Exception;
    
    
/**
     * Remove a key-value pair from cacheMap by it's key
     * It can be called by any class
     * 
     * 
@param key
     * 
@throws Exception
     
*/
    
public void removeData(String key) throws Exception{
        
try {
            lock.writeLock();
            remove(key);
        } 
finally {
            lock.writeUnlock();
        }
    }
    
    
/**
     * Remove a key-value pair from cacheMap by it's key
     * It only can be called by child-class
     * 
     * 
@param key
     * 
@return
     * 
@throws Exception
     
*/
    
protected abstract void remove(String key) throws Exception;
    
    
/**
     * Remove all data in the cacheMap
     * It can be called by any class
     * 
     * 
@throws Exception
     
*/
    
public void removeAllData() throws Exception{
        
try {
            lock.writeLock();
            removeAll();
        } 
finally {
            lock.writeUnlock();
        }
    }
    
    
/**
     * Remove all data in the cacheMap
     * It only can be called by child-class
     * 
     * 
@param key
     * 
@return
     * 
@throws Exception
     
*/
    
protected abstract void removeAll() throws Exception;
    
    
/**
     * Judge the date whether exceed the time limit
     * 
     * 
@param date
     * 
@return
     
*/
    
private static boolean isexceedTimeLimit(Date date){
        
long diff = (new Date()).getTime() - date.getTime();
        
        
return diff<Time_Limit_300;
    }
}

4.InnerCacheMap,用HashMap作为实际内存空间的Cache实现类:
import java.util.HashMap;
import java.util.Map;

import cachemap.base.AbstractCacheMap;
import cachemap.base.Data;

/**
 * CacheMap used local HashMap
 * 
 * 
@author heyang
 * @time Sep 23, 2011,3:48:17 PM
 
*/
public class InnerCacheMap extends AbstractCacheMap{
    
// essential storage
    private Map<String,Data> map;
    
    
/**
     * Contructor
     
*/
    
public InnerCacheMap(){
        
super();
        map
=new HashMap<String,Data>();
    }

    @Override
    
protected Data get(String key) throws Exception {
        
return map.get(key);
    }

    @Override
    
protected void set(String key, Data value) throws Exception {
        map.put(key, value);
    }

    @Override
    
protected boolean contains(String key) throws Exception {
        
return map.containsKey(key);
    }

    @Override
    
protected void remove(String key) throws Exception {
        map.remove(key);
    }

    @Override
    
protected void removeAll() throws Exception {
        map.clear();
    }
}

5.CacheMapSetter类,用于向Cache中异步写入数据:
import cachemap.base.AbstractCacheMap;


/**
 * CacheMapSetter
 * It's use is to set a key-value pair into cacheMap
 * 
 * 
@author heyang
 * @time Sep 26, 2011,10:11:36 AM
 
*/
public final class CacheMapSetter implements Runnable{
    
// The reference to the cacheMap
    private AbstractCacheMap cacheMap;
    
private String key;
    
private byte[] value;
    
    
/**
     * Constuctor
     * 
@param cacheMap
     * 
@param key
     * 
@param value
     
*/
    
public CacheMapSetter(AbstractCacheMap cacheMap,String key,byte[] value){
        
this.cacheMap=cacheMap;
        
this.key=key;
        
this.value=value;
        
        
new Thread(this).start();
    }

    @Override
    
public void run(){
        
try{
            cacheMap.writeData(key, value);        
        }
        
catch(Exception ex){
            ex.printStackTrace();
        }
    }
}


6.使用示例:
            // Get key
            String key=getKey(inputEnv);
            
            
// Get operation
            String operation=getOperation(inputEnv);
            
            
            
if("READ".equalsIgnoreCase(operation)){
                
if(cacheMap.containsKey(key)){
                    
byte[] value=cacheMap.readData(key);
                    
                    
// TODO:
                   .....   
                }
else{
                    
// TODO:
                    ... 
                }
            }
else if("WRITE".equalsIgnoreCase(operation)){
                
if(cacheMap.containsKey(key)){
                    cacheMap.removeData(key);
                }    
                
                
byte[] value=getValue(outputEnv);
                
new CacheMapSetter(cacheMap,key, value);
                
                
// TODO:
                ....               
            }
else if("REMOVEALL".equalsIgnoreCase(operation)){
                cacheMap.removeAllData();
                
                
// TODO:
                ....
            }
else{
                
throw new Exception("Unknown Operation:"+operation);
            }

以上类的代码下载:
posted on 2011-09-27 15:32 何杨 阅读(527) 评论(0)  编辑  收藏 所属分类: WMB

只有注册用户登录后才能发表评论。


网站导航: