2009-12-02 61 views
0

是否有一个Java API /建议改用System.currentTimeMillis的()来得到当前时间毫秒精度上的窗户 - 要求是两个连续调用同为1ms之间应该给两个睡眠时间不同的时间 - 目前我需要明确地睡15毫秒来获得不同的时间的Java毫秒精度

+0

你能利用当前的时间,然后每个循环中加1毫秒计数,并编写到数据库(它可能不准确,但它是唯一的).. – 2009-12-02 11:13:22

+0

系统.currentTimeMillis()取决于操作系统如何度量时间。 – nayakam 2009-12-02 11:21:49

+0

感谢输入 - 可能会实现一个内部计数器,并在预定的时间间隔重新同步时钟 - 注意:也许我应该用不同的方式措辞的问题 - 要求的时间戳不是生成的uid - 它用于版本控制,审计和查看历史上的特定时间和日期等数据等 – prabhackar 2009-12-03 20:38:54

回答

5

由于Java 1.5,你可以使用System.nanoTime()微基准测试以更高的精度。由于这是基于可能改变的固定时间(参见该方法的Javadoc),所以将其与System.currentTimeMillis()(例如,

String time = System.currentTimeMillis() + "" + System.nanoTime(); 
+1

相信它只用于经过时间 – prabhackar 2009-12-02 11:52:31

+0

正确的,要获得时间戳,它可能是有意义的,将它与'System.currentTimeMillis( )' – 2009-12-02 12:29:45

1

为什么你需要时间是独一无二的?

在交易开始时花时间为每个插入添加一个MS。

+0

数据版本化 - 没有事务本身 - 有时可能有同一实体的数据由两个线程更新,然后我得到的问题没有15毫秒的延迟 – prabhackar 2009-12-02 11:25:34

+0

更新更新为插入 – prabhackar 2009-12-02 11:26:45

+0

然后使用主键,而不是当前日期。 – 2009-12-03 09:07:03

3

这是一个窗口限制。如果在其他操作系统上调用System.currentTimeMillis(),则可以获得更高的精度。

我的建议是不要使用时间戳作为唯一性的来源。使用一个oracle序列,因为它是为这个问题设计的。否则,使用线程名称+ timetamp(yuk)。

或者你可以使用System.nanoTime(),但它只对时间差异有用,而不是绝对时间。

6

请勿尝试使用时间来创建唯一值。使用数据库生成一个唯一的ID(我假设的密钥)作为记录。可以使用自动递增字段,也可以使用单个记录创建单独的表,以保存可以安全锁定和更新的计数器。

尽管您可能会得到一个可行的解决方案,但计时防止资源冲突最终会迎头赶上。

+0

我同意,但我在一个阶段,它不可能做任何db设计更改 - 最坏的情况下延迟15ms生活 – prabhackar 2009-12-02 11:40:27

+1

@prabhackar,注意:如果系统时间关闭一些原因。我希望你确认时间戳不会倒退。 :) – PSpeed 2009-12-02 12:42:12

2

中的currentTimeMillis的分辨率()调用是依赖于底层操作系统,并为您的情况创造出独特的邮票不应加以依赖。考虑有一个UID-singleton,它可以给你一个长的值,每次调用都会增加一个值,然后使用它。

1

在这里区分准确性和准确性很重要。 System.currentTimeMillis()具有毫秒精度,但不能保证准确性,因为它从底层操作系统中获取,而操作系统从硬件获得,而不同的硬件时钟具有不同的精度。

使用该数据的版本是一个糟糕的主意,因为即使你有误差在毫秒级,你仍然运行偶尔冲突的风险,如果两件事情发生在同一毫秒。

0

虽然这是没有直接关系的问题,我从评论undestood原来的尝试是产生一些版本标识符。

这当然是一个糟糕的主意,正如其他海报在此详述。

如果您不能使用一个数据库,然后一个更好的主意是使用一个AtomicIntegerAtomicLong - 那么你可以调用getAndIncrement()incrementAndGet(),而不用担心任何可能出现的时序问题。

0

绝对时间分辨率为15ms的限制是你的操作系统&中断率的特点。我知道对于Linux来说,有一个内核补丁可以将分辨率提高到1ms(甚至可能是微秒?),虽然不确定Windows。正如其他人所评论的,相对时间可以使用System#nanoTime()(目前用于微秒精度)来解决。无论哪种方式,您都应该考虑使用数据库密钥(或类似的)来分配唯一的密钥。

链接

3

由于Java 1.5,你可以使用java.util.UUID生成唯一的ID。

public static void main(String[] args) 
    { 
     System.out.println("uuid=" + UUID.randomUUID().toString()); 
     System.out.println("uuid=" + UUID.randomUUID().toString()); 
    }