├── README.md
└── SnowFlake.java
/README.md:
--------------------------------------------------------------------------------
1 | # SnowFlake
2 | Twitter的雪花算法SnowFlake,使用Java语言实现。
3 |
4 | SnowFlake算法用来生成64位的ID,刚好可以用long整型存储,能够用于分布式系统中生产唯一的ID, 并且生成的ID有大致的顺序。
5 | 在这次实现中,生成的64位ID可以分成5个部分:
6 |
7 | `0 - 41位时间戳 - 5位数据中心标识 - 5位机器标识 - 12位序列号`
8 |
9 | 5位数据中心标识跟5位机器标识这样的分配仅仅是当前实现中分配的,如果业务有其实的需要,可以按其它的分配比例分配,如10位机器标识,不需要数据中心标识。
10 |
11 | 具体说明可以参考文章:
12 | [http://www.wolfbe.com/detail/201611/381.html](http://www.wolfbe.com/detail/201611/381.html)
13 |
14 |
15 | 生成的ID如下所示:
16 |
17 | 2099698216983
18 |
19 | 2099698216984
20 |
21 | 2099698216985
22 |
23 | 2099698216986
24 |
25 | 2099698216987
26 |
27 | 2099698216988
28 |
29 | 2099698216989
30 |
31 | 2099698216990
32 |
33 | 2099698216991
34 |
35 | 2099698216992
36 |
37 | 2099698216993
38 |
39 | 2099698216994
40 |
41 | 2099698216995
42 |
43 | 2099698216996
44 |
45 | 2099698216997
46 |
47 | 2099698216998
48 |
49 | 2099698216999
50 |
51 | 2099698217000
52 |
53 | 2099698217001
54 |
55 | 2099698217002
56 |
57 | 2099698217003
58 |
59 | 2099698217004
60 |
61 | 2099698217005
62 |
63 | 2099698217006
64 |
65 | 2099698217007
66 |
67 | 2099698217008
68 |
69 | 2099698217009
70 |
71 | 2099698217010
72 |
73 | 2099698217011
74 |
75 | 2099698217012
76 |
77 | 2099698217013
78 |
79 | 2099698217014
80 |
81 | 2099698217015
82 |
83 | 2099698217016
84 |
85 | 2099698217017
86 |
87 | 2099698217018
88 |
89 | 2099698217019
90 |
91 |
92 | ## 赞助
93 | 如果觉得项目还不错,想要表达些什么的话,可以上[爱淘汇:http://itao.wolfbe.com](http://itao.wolfbe.com) 领淘宝天猫的优惠券,领取优惠券再下单可以省不少钱喔。你们使用这些优惠券购买东西时,我也可以得到一些佣金的,多谢支持!!!
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/SnowFlake.java:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * twitter的snowflake算法 -- java实现
4 | *
5 | * @author beyond
6 | * @date 2016/11/26
7 | */
8 | public class SnowFlake {
9 |
10 | /**
11 | * 起始的时间戳
12 | */
13 | private final static long START_STMP = 1480166465631L;
14 |
15 | /**
16 | * 每一部分占用的位数
17 | */
18 | private final static long SEQUENCE_BIT = 12; //序列号占用的位数
19 | private final static long MACHINE_BIT = 5; //机器标识占用的位数
20 | private final static long DATACENTER_BIT = 5;//数据中心占用的位数
21 |
22 | /**
23 | * 每一部分的最大值
24 | */
25 | private final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT);
26 | private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT);
27 | private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT);
28 |
29 | /**
30 | * 每一部分向左的位移
31 | */
32 | private final static long MACHINE_LEFT = SEQUENCE_BIT;
33 | private final static long DATACENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT;
34 | private final static long TIMESTMP_LEFT = DATACENTER_LEFT + DATACENTER_BIT;
35 |
36 | private long datacenterId; //数据中心
37 | private long machineId; //机器标识
38 | private long sequence = 0L; //序列号
39 | private long lastStmp = -1L;//上一次时间戳
40 |
41 | public SnowFlake(long datacenterId, long machineId) {
42 | if (datacenterId > MAX_DATACENTER_NUM || datacenterId < 0) {
43 | throw new IllegalArgumentException("datacenterId can't be greater than MAX_DATACENTER_NUM or less than 0");
44 | }
45 | if (machineId > MAX_MACHINE_NUM || machineId < 0) {
46 | throw new IllegalArgumentException("machineId can't be greater than MAX_MACHINE_NUM or less than 0");
47 | }
48 | this.datacenterId = datacenterId;
49 | this.machineId = machineId;
50 | }
51 |
52 | /**
53 | * 产生下一个ID
54 | *
55 | * @return
56 | */
57 | public synchronized long nextId() {
58 | long currStmp = getNewstmp();
59 | if (currStmp < lastStmp) {
60 | throw new RuntimeException("Clock moved backwards. Refusing to generate id");
61 | }
62 |
63 | if (currStmp == lastStmp) {
64 | //相同毫秒内,序列号自增
65 | sequence = (sequence + 1) & MAX_SEQUENCE;
66 | //同一毫秒的序列数已经达到最大
67 | if (sequence == 0L) {
68 | currStmp = getNextMill();
69 | }
70 | } else {
71 | //不同毫秒内,序列号置为0
72 | sequence = 0L;
73 | }
74 |
75 | lastStmp = currStmp;
76 |
77 | return (currStmp - START_STMP) << TIMESTMP_LEFT //时间戳部分
78 | | datacenterId << DATACENTER_LEFT //数据中心部分
79 | | machineId << MACHINE_LEFT //机器标识部分
80 | | sequence; //序列号部分
81 | }
82 |
83 | private long getNextMill() {
84 | long mill = getNewstmp();
85 | while (mill <= lastStmp) {
86 | mill = getNewstmp();
87 | }
88 | return mill;
89 | }
90 |
91 | private long getNewstmp() {
92 | return System.currentTimeMillis();
93 | }
94 |
95 | public static void main(String[] args) {
96 | SnowFlake snowFlake = new SnowFlake(2, 3);
97 |
98 | for (int i = 0; i < (1 << 12); i++) {
99 | System.out.println(snowFlake.nextId());
100 | }
101 |
102 | }
103 | }
104 |
--------------------------------------------------------------------------------