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

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

无数据库方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* @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++;
}
}

有数据库方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* @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;
}
}

键值缓存方案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/**
* @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++;
}
}

多序列生成器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/**
* @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;
}
}

集合管理生成器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
* @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;
}
}
作者

光星

发布于

2021-02-22

更新于

2022-06-17

许可协议

评论