2009-12-02 59 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()); 
    }