Skip to content

Commit 4ff4618

Browse files
committed
添加了Twitter ID生成算法的工具,每秒支持12万ID生成。
1 parent f2d1c38 commit 4ff4618

File tree

2 files changed

+232
-84
lines changed

2 files changed

+232
-84
lines changed
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
package com.github.xiaour.utils;
2+
3+
import java.util.Date;
4+
import java.util.Random;
5+
import java.util.concurrent.CountDownLatch;
6+
import java.util.concurrent.ExecutorService;
7+
import java.util.concurrent.Executors;
8+
9+
/**
10+
* @Author: Xiaour
11+
* @Description: 一个基于Twitter的
12+
* @Date: 2018/8/22 14:24
13+
*/
14+
public class IDGenerate {
15+
16+
private static final long startTimeStamp = 1534919378079L; //定义一个起始时间 new Date().getTime()
17+
18+
private static final long workerIdBits = 6L;
19+
private static final long dataCenterIdBits = 6L;
20+
private static final long maxWorkerId = -1L ^ (-1L << workerIdBits);
21+
private static final long maxDataCenterId = -1L ^ (-1L << dataCenterIdBits);
22+
23+
private static final long sequenceBits = 14L;
24+
private static final long workerIdShift = sequenceBits;
25+
private static final long dataCenterIdShift = sequenceBits + workerIdBits;
26+
private static final long timestampLeftShift = sequenceBits + workerIdBits + dataCenterIdBits;
27+
private static final long sequenceMask = -1L ^ (-1L << sequenceBits);
28+
private static final Random r = new Random();
29+
30+
private final long workerId;
31+
private final long dataCenterId;
32+
private final long idEpoch;
33+
private long lastTimestamp = -1L;
34+
private long sequence = 0;
35+
36+
public IDGenerate() {
37+
this(startTimeStamp);
38+
}
39+
40+
public IDGenerate(long idEpoch) {
41+
this(r.nextInt((int) maxWorkerId), r.nextInt((int) maxDataCenterId), 0, idEpoch);
42+
}
43+
44+
public IDGenerate(long workerId, long dataCenterId, long sequence) {
45+
this(workerId, dataCenterId, sequence, startTimeStamp);
46+
}
47+
48+
public IDGenerate(long workerId, long dataCenterId, long sequence, long idEpoch) {
49+
this.workerId = workerId;
50+
this.dataCenterId = dataCenterId;
51+
this.sequence = sequence;
52+
this.idEpoch = idEpoch;
53+
54+
if (workerId < 0 || workerId > maxWorkerId) {
55+
throw new IllegalArgumentException("workerId is illegal: " + workerId);
56+
}
57+
if (dataCenterId < 0 || dataCenterId > maxDataCenterId) {
58+
throw new IllegalArgumentException("dataCenterId is illegal: " + dataCenterId);
59+
}
60+
61+
if (idEpoch >= timeGen()) {
62+
throw new IllegalArgumentException("idEpoch is illegal: " + idEpoch);
63+
}
64+
}
65+
66+
public long getDataCenterId() {
67+
return dataCenterId;
68+
}
69+
70+
public long getWorkerId() {
71+
return workerId;
72+
}
73+
74+
public long getTime() {
75+
return timeGen();
76+
}
77+
78+
public synchronized long nextId() {
79+
long timestamp = timeGen();
80+
if (timestamp < lastTimestamp) {
81+
throw new IllegalArgumentException("Clock moved backwards.");
82+
}
83+
84+
if (lastTimestamp == timestamp) {
85+
sequence = (sequence + 1) & sequenceMask;
86+
if (sequence == 0) {
87+
timestamp = tilNextMillis(lastTimestamp);
88+
}
89+
} else {
90+
sequence = 0;
91+
}
92+
93+
lastTimestamp = timestamp;
94+
long id = ((timestamp - idEpoch) << timestampLeftShift) | (dataCenterId <<
95+
dataCenterIdShift) | (workerId << workerIdShift) | sequence;
96+
return id;
97+
}
98+
99+
public long getIdTimestamp(long id) {
100+
return idEpoch + (id >> timestampLeftShift);
101+
}
102+
103+
private long tilNextMillis(long lastTimestamp) {
104+
long timestamp = timeGen();
105+
while (timestamp <= lastTimestamp) {
106+
timestamp = timeGen();
107+
}
108+
109+
return timestamp;
110+
}
111+
112+
private long timeGen() {
113+
return System.currentTimeMillis();
114+
}
115+
116+
@Override
117+
public String toString() {
118+
final StringBuilder sb = new StringBuilder("IdBitWorker{");
119+
sb.append("workerId=").append(workerId);
120+
sb.append(", dataCenterId=").append(dataCenterId);
121+
sb.append(", idEpoch=").append(idEpoch);
122+
sb.append(", lastTimestamp=").append(lastTimestamp);
123+
sb.append(", sequence=").append(sequence);
124+
sb.append('}');
125+
return sb.toString();
126+
}
127+
128+
public static void main(String[] args) throws Exception {
129+
IDGenerate worker = new IDGenerate();
130+
ExecutorService executor = Executors.newFixedThreadPool(8);
131+
132+
CountDownLatch countDownLatch = new CountDownLatch(1000000);
133+
Runnable run = () -> {
134+
//这里是最主要ID部分
135+
System.out.println(worker.nextId());
136+
countDownLatch.countDown();
137+
};
138+
139+
long startTime = System.currentTimeMillis();
140+
for (int i = 0; i < 1000000; i++) {
141+
executor.execute(run);
142+
}
143+
countDownLatch.await();
144+
System.out.println(System.currentTimeMillis() - startTime);
145+
executor.shutdown();
146+
147+
System.out.println(new Date().getTime());
148+
}
149+
}
Lines changed: 83 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,85 +1,84 @@
1-
package com.github.xiaour.utils;
2-
3-
4-
import com.google.gson.*;
5-
import com.google.gson.reflect.TypeToken;
6-
7-
import java.lang.reflect.Type;
8-
import java.util.ArrayList;
9-
import java.util.HashMap;
10-
import java.util.List;
11-
import java.util.Map;
12-
13-
public class JsonUtil{
14-
15-
16-
private static Gson gson = null;
17-
18-
static{
19-
gson = new Gson();
20-
}
21-
22-
public static synchronized Gson newInstance(){
23-
if(gson == null){
24-
gson = new Gson();
25-
}
26-
return gson;
27-
}
28-
29-
public static String getJsonString(Object obj){
30-
return gson.toJson(obj);
31-
}
32-
33-
public static <T> T toBean(String json,Class<T> clz){
34-
35-
return gson.fromJson(json, clz);
36-
}
37-
38-
public static <T> Map<String, T> readJson2MapObj(String json,Class<T> clz){
39-
Map<String, JsonObject> map = gson.fromJson(json, new TypeToken<Map<String,JsonObject>>(){}.getType());
40-
Map<String, T> result = new HashMap<>();
41-
for(String key:map.keySet()){
42-
result.put(key,gson.fromJson(map.get(key),clz) );
43-
}
44-
return result;
45-
}
46-
47-
public static <T> T json2Obj(String json,Class<T> clz){
48-
return gson.fromJson(json,clz);
49-
}
50-
51-
public static Map<String, Object> toMap(String json){
52-
Map<String, Object> map = gson.fromJson(json, new TypeToken<Map<String,Object>>(){}.getType());
53-
return map;
54-
}
55-
56-
public static Map<String,String> readJsonStrMap(String json) {
57-
Map<String, JsonObject> map = gson.fromJson(json, new TypeToken<Map<String,JsonObject>>(){}.getType());
58-
Map<String,String> result = new HashMap<>();
59-
for(String key:map.keySet()){
60-
result.put(key,gson.fromJson(map.get(key),String.class) );
61-
}
62-
return result;
63-
}
64-
65-
public static Map<byte[], byte[]> readJsonByteMap(String json) {
66-
Map<String, JsonPrimitive> map = gson.fromJson(json, new TypeToken<Map<String,JsonPrimitive>>(){}.getType());
67-
Map<byte[], byte[]> vmap = new HashMap<>();
68-
for(String key:map.keySet()){
69-
vmap.put(key.getBytes(),gson.fromJson(map.get(key),String.class).getBytes() );
70-
}
71-
return vmap;
72-
73-
}
74-
75-
76-
public static <T> List<T> readJson2Array(String json, Class<T> clz){
77-
JsonArray array = new JsonParser().parse(json).getAsJsonArray();
78-
List<T> list = new ArrayList<>();
79-
for(final JsonElement elem : array){
80-
list.add(gson.fromJson(elem, (Type)clz));
81-
}
82-
return list;
83-
}
84-
1+
package com.github.xiaour.utils;
2+
3+
import com.google.gson.*;
4+
import com.google.gson.reflect.TypeToken;
5+
6+
import java.lang.reflect.Type;
7+
import java.util.ArrayList;
8+
import java.util.HashMap;
9+
import java.util.List;
10+
import java.util.Map;
11+
12+
public class JsonUtil{
13+
14+
15+
private static Gson gson = null;
16+
17+
static{
18+
gson = new Gson();
19+
}
20+
21+
public static synchronized Gson newInstance(){
22+
if(gson == null){
23+
gson = new Gson();
24+
}
25+
return gson;
26+
}
27+
28+
public static String getJsonString(Object obj){
29+
return gson.toJson(obj);
30+
}
31+
32+
public static <T> T toBean(String json,Class<T> clz){
33+
34+
return gson.fromJson(json, clz);
35+
}
36+
37+
public static <T> Map<String, T> readJson2MapObj(String json,Class<T> clz){
38+
Map<String, JsonObject> map = gson.fromJson(json, new TypeToken<Map<String,JsonObject>>(){}.getType());
39+
Map<String, T> result = new HashMap<>();
40+
for(String key:map.keySet()){
41+
result.put(key,gson.fromJson(map.get(key),clz) );
42+
}
43+
return result;
44+
}
45+
46+
public static <T> T json2Obj(String json,Class<T> clz){
47+
return gson.fromJson(json,clz);
48+
}
49+
50+
public static Map<String, Object> toMap(String json){
51+
Map<String, Object> map = gson.fromJson(json, new TypeToken<Map<String,Object>>(){}.getType());
52+
return map;
53+
}
54+
55+
public static Map<String,String> readJsonStrMap(String json) {
56+
Map<String, JsonObject> map = gson.fromJson(json, new TypeToken<Map<String,JsonObject>>(){}.getType());
57+
Map<String,String> result = new HashMap<>();
58+
for(String key:map.keySet()){
59+
result.put(key,gson.fromJson(map.get(key),String.class) );
60+
}
61+
return result;
62+
}
63+
64+
public static Map<byte[], byte[]> readJsonByteMap(String json) {
65+
Map<String, JsonPrimitive> map = gson.fromJson(json, new TypeToken<Map<String,JsonPrimitive>>(){}.getType());
66+
Map<byte[], byte[]> vmap = new HashMap<>();
67+
for(String key:map.keySet()){
68+
vmap.put(key.getBytes(),gson.fromJson(map.get(key),String.class).getBytes() );
69+
}
70+
return vmap;
71+
72+
}
73+
74+
75+
public static <T> List<T> readJson2Array(String json, Class<T> clz){
76+
JsonArray array = new JsonParser().parse(json).getAsJsonArray();
77+
List<T> list = new ArrayList<>();
78+
for(final JsonElement elem : array){
79+
list.add(gson.fromJson(elem, (Type)clz));
80+
}
81+
return list;
82+
}
83+
8584
}

0 commit comments

Comments
 (0)