最近看<JAVA与模式>,单例章节的例子,我作了修改之后的练习,用properties文件代替数据库,略有不同。
需求:某个系统需要的多键值生成器,键值唯一,键值缓存(避免多次访问,节约资源)
实现:
一个标准单例:
package singleton.keyGenerator;
import java.util.HashMap;
public class KeyGenerator {
private static KeyGenerator keyGenerator = new KeyGenerator();
private HashMap<String, KeyBuffer> KeyPool = new HashMap<String, KeyBuffer>();//缓存
private KeyGenerator() {
}
public static KeyGenerator getInstance() {
return keyGenerator;
}
//第一次使用,放入缓存,否则直接使用
public int getNextKey(String key) {
if (!KeyPool.containsKey(key)) {
KeyPool.put(key, new KeyBuffer(key));
}
return KeyPool.get(key).getNextVal(key);
}
}
单键的缓存:
package singleton.keyGenerator;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
//单键值的缓存类
public class KeyBuffer {
private int nextKey;
private int maxKey;
// 键缓存大小
private int PoolSize = 3;
public KeyBuffer(String key) {
getFromFile(key);
}
public synchronized int getNextVal(String key) {
if (nextKey > maxKey) {
getFromFile(key);
}
return nextKey++;
}
private synchronized void getFromFile(String key) {
Properties prop = new Properties();
System.out.println("ReadFromFile:"+key);
try {
InputStream in = new FileInputStream("c:\\key.properties");
prop.load(in);
if (!prop.containsKey(key)) {
//文件中没有此键,异常
throw new RuntimeException("key not defined");
}
nextKey = Integer.valueOf((String) prop.get(key)) + 1;
maxKey = nextKey + PoolSize - 1;
in.close();
//
OutputStream out = new FileOutputStream("c:\\key.properties");
prop.setProperty(key, Integer.toString(maxKey));
prop.store(out, "From KeyGenerator");
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
测试:
package singleton.keyGenerator;
public class Client {
public static void main(String[] args) {
KeyGenerator keyGenerator = KeyGenerator.getInstance();
System.out.println(keyGenerator.getNextKey("KEY"));
System.out.println(keyGenerator.getNextKey("NEWKEY"));
System.out.println(keyGenerator.getNextKey("KEY"));
System.out.println(keyGenerator.getNextKey("NEWKEY"));
System.out.println(keyGenerator.getNextKey("KEY"));
System.out.println(keyGenerator.getNextKey("NEWKEY"));
System.out.println(keyGenerator.getNextKey("KEY"));
System.out.println(keyGenerator.getNextKey("NEWKEY"));
System.out.println(keyGenerator.getNextKey("KEY"));
System.out.println(keyGenerator.getNextKey("NEWKEY"));
}
}
测试结果:
ReadFromFile:KEY
71
ReadFromFile:NEWKEY
1016
72
1017
73
1018
ReadFromFile:KEY
74
ReadFromFile:NEWKEY
1019
75
1020
文件 key.properties
#From KeyGenerator
#Fri Jan 24 20:33:20 CST 2014
KEY=76
NEWKEY=1021
总结:单例是个很有意思的模式