几种简单的序列号生成器的实现方式,涉及了单例模式使用,多例集合管理。
无数据库方式
/**
* @desc 单机没数据库方式,
* 存在明显缺点:系统重启后KeyGenerator会被重新初始化
*/
public class KeyGenerator {
private static KeyGenerator keygen = new KeyGenerator();
private int key = 1000;
private KeyGenerator() {
}
private KeyGenerator getInstance() {
return keygen;
}
public synchronized int getNextKey() {
return key++;
}
}
有数据库方式
/**
* @desc 有数据库方式, 缺点:每次都要查数据库,性能损耗大
*/
public class KeyGenerator {
private static KeyGenerator keygen = new KeyGenerator();
private KeyGenerator() {
}
private KeyGenerator getInstance() {
return keygen;
}
public synchronized int getNextKey() {
return getNextKeyFromDB();
}
/**
* 注意:是先将新的键值写入到表,然后查出返回
* 这样,即使该序列号在业务层使用失败,最多是该序列号浪费,不影响后续使用
* @return
*/
private int getNextKeyFromDB() {
String sql1 = "UPDATE key_table SET value = value + 1";
String sql2 = "SELECT value FROM key_table";
//示意性地返回一个数值
return 1000;
}
}
键值缓存方案
/**
* @desc 健值缓存方式
*/
public class KeyGenerator {
private static KeyGenerator keygen = new KeyGenerator();
private static final int POOL_SIZE = 20;
private KeyInfo keyInfo;
private KeyGenerator() {
keyInfo = new KeyInfo(POOL_SIZE);
}
public static KeyGenerator getInstance() {
return keygen;
}
public synchronized int getNextKey() {
return keyInfo.getNextKey();
}
}
/**
* @desc 缓存方式, 键值写库增加不是 +1, 而是增加一个范围池;
* 当超过最大值时,再次写库
*/
public class KeyInfo {
private int poolSize;
private int keyMin;
private int keyMax;
private int nextKey;
public KeyInfo() {
}
public KeyInfo(int poolSize) {
this.poolSize = poolSize;
retrieveFromDB();
}
/**
* 键值增加不是 +1, 而是增加一个范围池
*/
private void retrieveFromDB() {
String sql1 = "UPDATE key_table SET value = value + " + poolSize;
String sql2 = "SELECT value FROM key_table";
// 示意性地返回一个数值
int keyFromDB = 1000;
keyMax = keyFromDB;
keyMin = keyFromDB - poolSize + 1;
nextKey = keyMin;
}
public int getKeyMin() {
return keyMin;
}
public int getKeyMax() {
return keyMax;
}
public int getNextKey() {
if (nextKey > keyMax) {
retrieveFromDB();
}
return nextKey++;
}
}
多序列生成器
/**
* @desc 有缓存的多序列键生成器,生成器使用单例方式
* 使用聚集缓存多例健值对象
*/
public class KeyGenerator {
private static KeyGenerator keygen = new KeyGenerator();
private HashMap<String, KeyInfo> keyInfoMap = new HashMap<>(10);
private static final int POOL_SIZE = 20;
private KeyGenerator() {
}
public static KeyGenerator getInstance() {
return keygen;
}
public synchronized int getNextKey(String key) {
KeyInfo keyInfo;
if (keyInfoMap.containsKey(key)) {
keyInfo = keyInfoMap.get(key);
} else {
keyInfo = new KeyInfo(POOL_SIZE, key);
keyInfoMap.put(key, keyInfo);
}
return keyInfo.getNextKey();
}
}
/**
* @desc 序列键
*/
public class KeyInfo {
private int poolSize;
private int keyMin;
private int keyMax;
private int nextKey;
private String key;
public KeyInfo() {
}
public KeyInfo(int poolSize, String key) {
this.poolSize = poolSize;
this.key = key;
retrieveFromDB(key);
}
public int getKeyMin() {
return keyMin;
}
public int getKeyMax() {
return keyMax;
}
public int getNextKey() {
if (nextKey > keyMax) {
retrieveFromDB();
}
return nextKey++;
}
private void retrieveFromDB(String key) {
String sql1 = "UPDATE key_table SET value = value + " + poolSize + "WHERE key = " + key;
String sql2 = "SELECT value FROM key_table WHERE key = " + key;
// 示意性地返回一个数值
int keyFromDB = 1000;
keyMax = keyFromDB;
keyMin = keyFromDB - poolSize + 1;
nextKey = keyMin;
}
}
集合管理生成器
/**
* @desc 有缓存的多序列键生成器, 使用聚集缓存多例生成器
*/
public class KeyGenerator {
private static HashMap<String, KeyGenerator> keygenMap = new HashMap<>(10);
private static final int POOL_SIZE = 20;
private KeyInfo keyInfo;
private KeyGenerator() {
}
private KeyGenerator(String key) {
keyInfo = new KeyInfo(POOL_SIZE, key);
}
public static synchronized KeyGenerator getInstance(String key) {
KeyGenerator keygen;
if (keygenMap.containsKey(key)) {
keygen = keygenMap.get(key);
} else {
keygen = new KeyGenerator(key);
keygenMap.put(key, keygen);
}
return keygen;
}
public synchronized int getNextKey() {
return keyInfo.getNextKey();
}
}
/**
* @desc 序列键
*/
public class KeyInfo {
private int poolSize;
private int keyMin;
private int keyMax;
private int nextKey;
private String key;
public KeyInfo() {
}
public KeyInfo(int poolSize, String key) {
this.poolSize = poolSize;
this.key = key;
retrieveFromDB(key);
}
public int getKeyMin() {
return keyMin;
}
public int getKeyMax() {
return keyMax;
}
public int getNextKey() {
if (nextKey > keyMax) {
retrieveFromDB();
}
return nextKey++;
}
private void retrieveFromDB(String key) {
String sql1 = "UPDATE key_table SET value = value + " + poolSize + "WHERE key = " + key;
String sql2 = "SELECT value FROM key_table WHERE key = " + key;
// 示意性地返回一个数值
int keyFromDB = 1000;
keyMax = keyFromDB;
keyMin = keyFromDB - poolSize + 1;
nextKey = keyMin;
}
}
更多内容请访问:IT源点
注意:本文归作者所有,未经作者允许,不得转载