[color=green][size=medium]程序目的:为了练习刚刚复习的Thread及刚刚学习的Timer。[/size][/color]
设计思路: 我们都知道,缓存是加快数据访问的非常重要的一种手段。现在,假设我们的内存中有多个缓存块(即内存块),为了确保数据的一致性,我们希望能够定时对这些缓存块进行数据同步,通过Timer,我们可以轻松实现这一目的。
概要:
项目包含3个类:
MemoryBlock 缓存块
MemoryBlockManager 缓存管理类,集中负责缓存块的添加及同步
SyncMemTask TimerTask的子类,用于执行同步任务
类图:
[img]http://dl.iteye.com/upload/attachment/227155/52195897-6cf6-3835-8807-4b9f4ff00e5e.png[/img]
代码:
MemroyBlock.java
/**
* MemoryBlock.java
*
*/
import java.util.*;
/**
* 内存块类,模拟在内存中缓存K-V值对,本版本仅仅处理String-String类型的数据对。
* @author Kevin
* 2010-3-30
*/
public class MemoryBlock {
//包装Map对象,以Map作为存储形式
private Map<String,String> memBlock;
//构造器,由于考虑到同步问题,所以使用了Hashtable,而不是HashMap
public MemoryBlock(){
this.memBlock = new Hashtable<String, String>();
}
/**
* 根据key返回缓存中对应的value
* @param key 待查找的键值
* @return 如果key存在,则返回与key对应的value,否则返回""。
*/
public String get(String key){
if(containsKey(key))
return this.memBlock.get(key);
else
return "";
}
/**
* 判断缓存中是否包含给定key
* @param key 待查找的键值
* @return 如果存在返回true,否则返回false
*/
public boolean containsKey(String key){
return this.memBlock.containsKey(key);
}
/**
* 将Key-Value插入到缓存中
* @param key 插入键值
* @param val 与键值对应的value
*/
public void put(String key, String val){
this.memBlock.put(key, val);
}
/**
* 从缓存中移除一对Key-Value
* @param key 待移除的键值
*/
public void remove(String key){
this.memBlock.remove(key);
}
/**
* 将缓存与目标缓存进行同步,将在目标缓存中但未在本缓存中的对象插入本缓存<br>
* 如果目标缓存中包含与本缓存相同的key值,但value不同,本缓存的value值将被<br>
* 覆盖。
* @param target 目标缓存
*/
public void syncWith(MemoryBlock target){
//通过Map.putAll()方法实现
this.memBlock.putAll(target.getMapBlock());
}
/**
* 以Map<K,V>的形式获得缓存中的数据,本方法主要用于实现syncWith同步功能
* @return 返回缓存的Map对象
*/
public Map<String,String> getMapBlock(){
return this.memBlock;
}
/**
* 清空缓存。
*/
public void clear(){
this.memBlock.clear();
}
public String toString(){
return this.memBlock.toString();
}
}
MemoryBlockManager.java
/**
* MemoryBlockManager.java
*
*/
import java.lang.*;
import java.util.*;
/**
* 缓存管理者,主要负责对多个缓存进行同步。
* @author Kevin
* 2010-3-30
*/
public class MemoryBlockManager implements Runnable{
//管理的多个缓存,存储与List中。
private List<MemoryBlock> blockList ;
//Timer任务,主要负责后台周期性同步缓存。
private Timer syncMemTimer;
public MemoryBlockManager(){
this.blockList = new LinkedList<MemoryBlock>();
this.syncMemTimer = new Timer();
//建立后台定时任务,每3s同步一次队列中的缓存。
this.syncMemTimer.schedule(new SyncMemTask(this.blockList), 1000, 3000);
}
/**
* 缓存注册。像缓存管理者添加新的缓存
* @param block
*/
public void registerMemoryBlcok(MemoryBlock block){
this.blockList.add(block);
}
public void run(){
Random rd = new Random();
for(int i=0;i<100;i++){
//从缓存列表中随机取得一个缓存,向其中插入一对值
MemoryBlock mb = this.blockList.get(rd.nextInt(this.blockList.size()));
//随机生一个100以内的整数,并和一个高斯数关联插入
mb.put(String.valueOf(rd.nextInt(100)), String.valueOf(rd.nextGaussian()));
try {
//休眠一秒,即每秒执行以此插入操作
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
SyncMemTask.java
import java.util.TimerTask;
import java.util.*;
/**
* SyncMemTask.java
*
*/
/**
* 用于同步缓存的任务类
* @author Kevin
* 2010-3-30
*/
public class SyncMemTask extends TimerTask {
//需要同步的缓存队列
private List<MemoryBlock> blockList ;
//临时用于存储缓存的对象
private MemoryBlock tmp;
/**
* 同步任务逻辑实现。
* @see java.util.TimerTask#run()
*/
public void run() {
System.out.println("Before sync");
//遍历队列中的每一个缓存
for(MemoryBlock block : blockList){
//输出缓存中的数据
System.out.println(block);
//将tmp与缓存同步
tmp.syncWith(block);
}
System.out.println("After sync:");
//再次遍历缓存 用于同步将每一个缓存与tmp同步
for(MemoryBlock block : blockList){
block.syncWith(tmp);
System.out.println(block);
}
//清空tmp 用于下次缓存的同步
tmp.clear();
}
public SyncMemTask(List<MemoryBlock> list){
this.blockList = list;
this.tmp = new MemoryBlock();
}
}
随便编写一个简单的Main程序:
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
MemoryBlockManager memBlockManager = new MemoryBlockManager();
memBlockManager.registerMemoryBlcok(new MemoryBlock());
memBlockManager.registerMemoryBlcok(new MemoryBlock());
memBlockManager.registerMemoryBlcok(new MemoryBlock());
new Thread(memBlockManager).start();
}
}
得到运行结果:
[img]http://dl.iteye.com/upload/attachment/227163/0daac28e-b4f4-3cd1-bb9d-6c2f65779f69.png[/img]
[color=red]
[size=large]后记[/size][/color]
这是一个非常粗糙的原型,只能处理String对,并且模拟的是在单机上的缓存同步,现实应用意义不大,但是很容易改造成可以简单处理分布式缓存的程序,具体的实现方法可能需要具体商榷。