WMB入门之十三:使用在Subflow中比较简陋的Cache设计 增加时效处理

WMB入门之十三:使用在Subflow中比较简陋的Cache设计 增加时效处理
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);
            }

以上类的代码下载:
http://www.blogjava.net/Files/heyang/FiveCacheClasses.rar

你可能感兴趣的:(WMB入门之十三:使用在Subflow中比较简陋的Cache设计 增加时效处理)