Utils:序列号生成器实现方式

star2017 1年前 ⋅ 432 阅读

几种简单的序列号生成器的实现方式,涉及了单例模式使用,多例集合管理。

无数据库方式

/**
 * @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源点

全部评论: 0

    我有话说: