【问题标题】:Not getting unique timestamp没有得到唯一的时间戳
【发布时间】:2011-11-04 11:42:28
【问题描述】:

我正在为要存储的对象生成唯一 ID

我在其中包含时间戳

但我运行了 for 循环

    for (int i = 0; i < 100; i++) {

        long time = Calendar.getInstance().getTimeInMillis();
        st = Integer.toHexString((int) time);
        System.out.printf("%d %s %d %n", i, st, st.length());
    }

我没有得到唯一的

我插入了Thread.sleep(15),然后它给了我独特的价值

还有其他方法可以让我获得独特的价值吗?

【问题讨论】:

  • 如果您预计循环每次迭代花费的时间超过一毫秒,那么您必须习惯于在非常慢的机器上运行。

标签: java uniqueidentifier


【解决方案1】:

我会使用简单的longintAtomicLong.incrementAndGet 更简单,而且是线程安全的。 另一种可能性是使用UUID.randomUUID(),但它是一个 UUID,而不是数值。

【讨论】:

  • 'AtomicLong.incrementAndGet()' 看起来很有趣至少比插入'Thread.sleep()' 好
【解决方案2】:

您的循环在两次迭代之间花费的时间不到 1 毫秒,因此时间戳不会改变(这就是为什么添加睡眠调用可以让时钟有时间移动)。

您最好使用库调用,例如建议的 palacsint,或者自己管理 UID。这样做的可能性包括获取最后发布的 ID 并递增,尽管这对多线程有问题。

【讨论】:

    【解决方案3】:

    这里是唯一时间戳的 3 种方法:

    /** WITH LOCK */
    private static long lastTs1 = Long.MIN_VALUE;
    private static final long uniqueTs1() {
        long unique_ts = System.currentTimeMillis();
        synchronized (SmtpServer.class) { lastTs1 = unique_ts = unique_ts > lastTs1 ? unique_ts : lastTs1 + 1; }
        return unique_ts;
    }
    
    /** WITHOUT LOCK */
    private static AtomicLong lastTs2 = new AtomicLong(Long.MIN_VALUE);
    private static final long uniqueTs2() { return lastTs2.updateAndGet((v)->Math.max(v+1, System.currentTimeMillis())); }
    
    /** WITHOUT LOCK, WITHOUT extra class */
    private static AtomicLong lastTs3 = new AtomicLong(Long.MIN_VALUE);
    private static final long uniqueTs() {
        long expect, next = System.currentTimeMillis();
        do {
            expect = lastTs3.get();
            if(expect >= next) next = expect + 1;
        } while(!lastTs3.compareAndSet(expect, next));
        return next;
    }
    

    【讨论】:

      【解决方案4】:

      试试这个。

      public class DateTimeService {
      
          @Autowired
          private Clock clock;
          private LocalDateTime current;
      
          @PostConstruct
          public void init() {
              current = LocalDateTime.now(clock);
          }
      
          public synchronized LocalDateTime getUniqueTimestamp() {
              LocalDateTime now = LocalDateTime.now(clock);
              if (current.isEqual(now) || current.isAfter(now)) {
                  current = current.plus(1, ChronoUnit.MICROS);
              } else {
                  current = now;
              }
              return current;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-23
        • 1970-01-01
        • 2019-08-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多