2011-11-04 36 views
1

我生成唯一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),那么它给我的唯一值

有没有另外一种方法可以获得独特的价值?

+2

如果你期待你的循环是要采取比每次迭代毫秒,那么你必须使用一个很慢的机器上运行更长的时间。 –

回答

3

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

+0

'AtomicLong.incrementAndGet()'看起来很有趣 至少比插入'Thread.sleep()' – ajduke

1

您的循环在迭代之间进行的时间少于1ms,所以时间戳不会更改(这就是为什么添加呼叫进入睡眠状态会使时钟移动的原因)。

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

0

这里有独特的时间戳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; 
}