├── 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 | --------------------------------------------------------------------------------