zoukankan      html  css  js  c++  java
  • IdGenerator 唯一Id生成器

    1. public class IdGenerator {
    2.  
       
    3.  
      private final static long beginTs = 1483200000000L;
    4.  
       
    5.  
      private long lastTs = 0L;
    6.  
       
    7.  
      private long processId;
    8.  
      private int processIdBits = 10;
    9.  
       
    10.  
      private long sequence = 0L;
    11.  
      private int sequenceBits = 12;
    12.  
       
    13.  
      public IdGenerator() {
    14.  
      }
    15.  
       
    16.  
      public IdGenerator(long processId) {
    17.  
      if (processId > ((1 << processIdBits) - 1)) {
    18.  
      throw new RuntimeException("进程ID超出范围,设置位数" + processIdBits + ",最大" + ((1 << processIdBits) - 1));
    19.  
      }
    20.  
      this.processId = processId;
    21.  
      }
    22.  
       
    23.  
      protected long timeGen() {
    24.  
      return System.currentTimeMillis();
    25.  
      }
    26.  
       
    27.  
      public synchronized long nextId() {
    28.  
      long ts = timeGen();
    29.  
      // 刚刚生成的时间戳比上次的时间戳还小,出错
    30.  
      if (ts < lastTs) {
    31.  
      throw new RuntimeException("时间戳顺序错误");
    32.  
      }
    33.  
      // 刚刚生成的时间戳跟上次的时间戳一样,则需要生成一个sequence序列号
    34.  
      if (ts == lastTs) {
    35.  
      // sequence循环自增
    36.  
      sequence = (sequence + 1) & ((1 << sequenceBits) - 1);
    37.  
      // 如果sequence=0则需要重新生成时间戳
    38.  
      if (sequence == 0) {
    39.  
      // 且必须保证时间戳序列往后
    40.  
      ts = nextTs(lastTs);
    41.  
      }
    42.  
      // 如果ts>lastTs,时间戳序列已经不同了,此时可以不必生成sequence了,直接取0
    43.  
      } else {
    44.  
      sequence = 0L;
    45.  
      }
    46.  
      // 更新lastTs时间戳
    47.  
      lastTs = ts;
    48.  
      return ((ts - beginTs) << (processIdBits + sequenceBits)) | (processId << sequenceBits) | sequence;
    49.  
      }
    50.  
       
    51.  
      public Long nextShortId() {
    52.  
      Long shortId = System.currentTimeMillis() / 100 % 1000000000;
    53.  
      if (shortId < 100000000) {
    54.  
      shortId += 100000000;
    55.  
      }
    56.  
      return shortId;
    57.  
      }
    58.  
       
    59.  
      protected long nextTs(long lastTs) {
    60.  
      long ts = timeGen();
    61.  
      while (ts <= lastTs) {
    62.  
      ts = timeGen();
    63.  
      }
    64.  
      return ts;
    65.  
      }
    66.  
       
    67.  
      }

    试一下这个算法的效率:

    1.  
      public static void main(String[] args) throws Exception {
    2.  
      // TODO Auto-generated method stub
    3.  
      IdGenerator ig = new IdGenerator(1023);
    4.  
      Long start = System.currentTimeMillis();
    5.  
      Set<Long> set = new HashSet<Long>();
    6.  
      for (int i = 0; i < 100000; i++) {
    7.  
      set.add(ig.nextId());
    8.  
      }
    9.  
      System.out.println(set.size());
    10.  
      System.out.println(System.currentTimeMillis() - start);
    11.  
      }

    结果:

    set.size(): 100000
    time:115

  • 相关阅读:
    oracle字符集查看修改
    oracle查看所有表及字段
    oracle重新启动步骤
    oracle job 定时执行 存储过程
    oracle导入导出exp,imp
    oracle创建表空间
    Oracle Dataguard HA (主备,灾备)方案部署调试
    Moving Tables-贪心
    Windows下Android开发环境配置
    在单进程单线程或单进程多线程下实现log4cplus写日志并按大小切割
  • 原文地址:https://www.cnblogs.com/telwanggs/p/13094983.html
Copyright © 2011-2022 走看看