Guest User

Untitled

a guest
Oct 18th, 2018
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.74 KB | None | 0 0
  1. public class IdWorker {
  2.  
  3. //开始该类生成ID的时间截,1288834974657 (Thu, 04 Nov 2010 01:42:54 GMT) 这一时刻到当前时间所经过的毫秒数,占 41 位(还有一位是符号位,永远为 0)。
  4. private final long startTime = 1463834116272L;
  5.  
  6. //机器id所占的位数
  7. private long workerIdBits = 5L;
  8.  
  9. //数据标识id所占的位数
  10. private long datacenterIdBits = 5L;
  11.  
  12. //支持的最大机器id,结果是31,这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数(不信的话可以自己算一下,记住,计算机中存储一个数都是存储的补码,结果是负数要从补码得到原码)
  13. private long maxWorkerId = -1L ^ (-1L << workerIdBits);
  14.  
  15. //支持的最大数据标识id
  16. private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
  17.  
  18. //序列在id中占的位数
  19. private long sequenceBits = 12L;
  20.  
  21. //机器id向左移12位
  22. private long workerIdLeftShift = sequenceBits;
  23.  
  24. //数据标识id向左移17位
  25. private long datacenterIdLeftShift = workerIdBits + workerIdLeftShift;
  26.  
  27. //时间截向左移5+5+12=22位
  28. private long timestampLeftShift = datacenterIdBits + datacenterIdLeftShift;
  29.  
  30. //生成序列的掩码,这里为1111 1111 1111
  31. private long sequenceMask = -1 ^ (-1 << sequenceBits);
  32.  
  33. private long workerId;
  34.  
  35. private long datacenterId;
  36.  
  37. //同一个时间截内生成的序列数,初始值是0,从0开始
  38. private long sequence = 0L;
  39.  
  40. //上次生成id的时间截
  41. private long lastTimestamp = -1L;
  42.  
  43. public IdWorker(long workerId, long datacenterId){
  44. if(workerId < 0 || workerId > maxWorkerId){
  45. throw new IllegalArgumentException(
  46. String.format("workerId[%d] is less than 0 or greater than maxWorkerId[%d].", workerId, maxWorkerId));
  47. }
  48. if(datacenterId < 0 || datacenterId > maxDatacenterId){
  49. throw new IllegalArgumentException(
  50. String.format("datacenterId[%d] is less than 0 or greater than maxDatacenterId[%d].", datacenterId, maxDatacenterId));
  51. }
  52. this.workerId = workerId;
  53. this.datacenterId = datacenterId;
  54. }
  55.  
  56. //生成id
  57. public synchronized long nextId(){
  58. long timestamp = timeGen();
  59. if(timestamp < lastTimestamp){
  60. throw new RuntimeException(
  61. String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
  62. }
  63. //如果是同一时间生成的,则自增
  64. if(timestamp == lastTimestamp){
  65. sequence = (sequence + 1) & sequenceMask;
  66. if(sequence == 0){
  67. //生成下一个毫秒级的序列
  68. timestamp = tilNextMillis();
  69. //序列从0开始
  70. sequence = 0L;
  71. }
  72. }else{
  73. //如果发现是下一个时间单位,则自增序列回0,重新自增
  74. sequence = 0L;
  75. }
  76.  
  77. lastTimestamp = timestamp;
  78.  
  79. //看本文第二部分的结构图,移位并通过或运算拼到一起组成64位的ID
  80. return ((timestamp - startTime) << timestampLeftShift)
  81. | (datacenterId << datacenterIdLeftShift)
  82. | (workerId << workerIdLeftShift)
  83. | sequence;
  84. }
  85.  
  86. protected long tilNextMillis(){
  87. long timestamp = timeGen();
  88. if(timestamp <= lastTimestamp){
  89. timestamp = timeGen();
  90. }
  91. return timestamp;
  92. }
  93.  
  94. protected long timeGen(){
  95. return System.currentTimeMillis();
  96. }
  97.  
  98. public static void main(String[] args) {
  99.  
  100. class IdServiceThread implements Runnable {
  101. private Set<Long> set;
  102. @Autowired
  103. private IdService idService;
  104.  
  105. public IdServiceThread(Set<Long> set, IdService idService) {
  106. this.set = set;
  107. this.idService = idService;
  108. }
  109.  
  110. @Override
  111. public void run() {
  112. while (true) {
  113. long id = idService.nextId();
  114. System.out.println("duplicate:" + id);
  115. if (!set.add(id)) {
  116. System.out.println("duplicate:" + id);
  117. }
  118. }
  119. }
  120. }
  121.  
  122. Set<Long> set = new HashSet<Long>();
  123. for(int i=0;i<100;i++){
  124. Thread t1 = new Thread(new IdServiceThread(set, idService));
  125. t1.setDaemon(true);
  126. t1.start();
  127. try {
  128. Thread.sleep(30000);
  129. } catch (InterruptedException e) {
  130. e.printStackTrace();
  131. }
  132. }
  133. }
  134.  
  135. }
Add Comment
Please, Sign In to add comment