【发布时间】:2016-05-13 10:50:13
【问题描述】:
我想在我的应用程序中发生事件时附加时间戳。假设客户端创建了一个 Event 对象,并且我想将创建时间戳附加到 Event 对象。我可以在构造函数中使用 System.currentTimeMillis() 来做到这一点。如果 Event 对象的创建速度不超过每毫秒一次,则此方法可以正常工作。在这种情况下,每个 Event 对象都从 System.currentTimeMillis() 获得不同的值,因此 Event 对象是有序的。
但是,如果需要以比每毫秒一个对象更快的速率创建 Event 对象,那么我的逻辑就会中断。根据对象创建的速率,2 个或更多 Event 对象最终具有相同的创建时间戳(因为 System.currentTimeMillis 在快速连续调用时返回相同的值)
现在在这种情况下我如何对 Event 对象进行排序?我知道 System.nanoTime() 但这与时代无关。
我愿意将 Event 类中的创建时间戳存储为 2 个实例变量 - creationTimeInMS (long) 和 creationTimeInNS (long)
我不想使用支持纳秒精度的 java.sql.Timestamp
我是否可以利用 System.nanoTime 来提供事件对象的排序?
注意 - 可以保证事件的创建速度不会超过每纳秒 1 个。因此,纳秒精度就足够了
我使用的代码如下
class Event {
private long timestamp
public Event() {
...
timestamp = System.currentTimeMillis()
}
因此,如果多个线程以每毫秒 1 个以上的速率调用 Event 构造函数,则两个(或更多)Event 对象将获得相同的时间戳。
如果调用的速度不超过每纳秒一次,则 System.nanoTime() 应该返回唯一的数字。但是我不确定如何将此数字与时间戳结合使用。我是否将其添加到时间戳以生成纳秒精度时间?
【问题讨论】:
-
是否所有事件都在一个线程中处理/创建?如果是这样,一个简单的增量计数器(可能除了 ms 时间戳之外)就足够了。如果您真的对事件之间的精确时间感兴趣,这将无济于事,而只关心它们的顺序。
-
扩展@JoachimSauer 的回答:即使您使用多线程方法,也可以使用
AtomicLong作为计数器。至于您的问题:“无论如何我可以利用 System.nanoTime 来提供事件对象的排序吗?”这个我不明白。如果保证每 ns 创建事件的速度不快于 1,为什么时间戳(以 ns 为单位)不足以对对象进行排序?你能详细说明一下吗? -
@Turing85:没错,AtomicLong 是一个非常好的解决方案,即使是多线程的。 nanoTime 的问题在于它不能保证单调增加(特别是它可以并且会溢出)。因此,测量时间跨度通常很好(只要它们足够小),但不足以对带有时间戳的元素进行排序。
-
@JoachimSauer,事件是从多个线程创建的
-
@Turing85,在我的原始编辑中添加了一些注释