我想在应用程序中发生事件时附加时间戳。假设客户端创建一个Event对象,我想将一个创建时间戳附加到Event对象。我可以使用构造函数中的System.currentTimeMillis()来完成此操作。如果创建的Event对象的速度不超过每毫秒一次,则此方法可以正常工作。在这种情况下,每个Event对象从System.currentTimeMillis()获取不同的值,因此对事件对象进行排序。
但是,如果需要创建一个比每毫秒一个对象快的速率的事件对象,那么我的逻辑会中断。根据对象创建速率,2个或更多事件对象最终具有相同的创建时间戳(因为System.currentTimeMillis在快速连续调用时返回相同的值)
现在如何在这种情况下对Event对象进行排序?我知道System.nanoTime(),但这与epoch无关。
我愿意将Event类中的创建时间戳存储分为2个实例变量 - creationTimeInMS(long)和creationTimeInNS(long)
我不想java.sql.Timestamp支持nano第二精度
无论如何我可以利用System.nanoTime来提供事件对象的排序吗?
注意 - 保证事件的创建速度不会超过1纳秒。因此纳秒精度就足够了
我使用的代码如下
class Event {
private long timestamp
public Event() {
...
timestamp = System.currentTimeMillis()
}
因此,如果多个线程以高于1 /毫秒的速率调用Event构造函数,则两个(或更多)Event对象将获得相同的时间戳。
System.nanoTime()如果被调用的速度不超过每纳秒一次,则应返回唯一编号。但是我不确定如何将此数字与时间戳结合使用。我是否将其添加到时间戳以生成纳秒精度时间?
答案 0 :(得分:1)
依靠挂钟很难实现这一点,时间会发生碰撞而纳米秒的分辨率在实践中难以实现,快速解决方案是在记住其最后一个值的时间周围添加一个包装器。当然,不会在分布式环境中工作。
static class MonotonicClock{
private long last;
public MonotonicClock(){
last = System.currentTimeMillis();
}
public synchronized long getNext(){
long current = System.currentTimeMillis();
if(last < current){ // last seen is less than "now"
last = current;
}else{
last++; //collision, overclock the time
}
return last;
}
}
在分布式系统中,事情变得更加复杂。您可能需要查看Lamport timestamps和Vector Clocks。