我正在为要存储的对象生成唯一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)
,然后它给了我唯一的值
我有另一种获得独特价值的方式吗?
答案 0 :(得分:3)
我使用简单的long
或int
。 AtomicLong.incrementAndGet
更简单,它是线程安全的。
另一种可能性是使用UUID.randomUUID()但它是UUID,而不是数值。
答案 1 :(得分:1)
你的循环在迭代之间花费不到1毫秒,因此时间戳不会改变(这就是为什么添加一个睡眠调用会给时钟移动时间。)
您最好使用库调用,例如palacsint建议,或自己管理UID。这样做的可能性包括获取最后发布的ID和递增,尽管这对多线程有问题。
答案 2 :(得分: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;
}
答案 3 :(得分:0)
尝试一下。
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;
}
}