2012-02-08 20 views
10

Javaでは、特定のVMインスタンスで一意であることが保証されたタイムスタンプ(ミリ秒単位)を作成する必要があります。私。 System.currentTimeMillis()のスループットを抑えて、msごとに最大で1つの結果を返すようにする必要があります。どのようにそれを実装する上で任意のアイデアですか?Javaでユニークなタイムスタンプを作成する

+2

  • 大文字と小文字を区別しません* 1つの結果、EVエリーミス?一意のタイムスタンプが必要な場合は、各呼び出しで異なる値を返すことを保証したいと思います。 –

  • +0

    単調増加する必要がありますか?彼らは実際の時間と何らかの関係を持たなければなりませんか?それらは複数回にわたって一意でなければならないのですか? –

    答えて

    30

    これにより、可能な限り重複することなく現在の時刻を近づけることができます。

    private static final AtomicLong LAST_TIME_MS = new AtomicLong(); 
    public static long uniqueCurrentTimeMS() { 
        long now = System.currentTimeMillis(); 
        while(true) { 
         long lastTime = LAST_TIME_MS.get(); 
         if (lastTime >= now) 
          now = lastTime+1; 
         if (LAST_TIME_MS.compareAndSet(lastTime, now)) 
          return now; 
        } 
    } 
    

    1ミリ秒あたり1つのIDの制限を回避する1つの方法は、マイクロ秒のタイムスタンプを使用することです。すなわち、currentTimeMSに1000を掛ける。これにより、1000ミリ秒/ミリ秒が可能になる。

    注:NTP修正のために時間が後退すると、時間が追いつくまでに1回の呼び出しごとに1ミリ秒で進行します。 ;)

    +0

    ありがとう!正確に私が必要なもの! – Yrlec

    +0

    正しく使用すると、アプリケーションを再起動しても固有のIDを持つことになります。 –

    +1

    いいね! 「正確に使用される」とは、より正確に何を意味しますか? – Yrlec

    1

    最も正確な利用可能なシステムタイマーであるSystem.nanoTime()を使用して、百万分の1秒を分けることができます。更新頻度に関する正式な保証はありませんが、1ミリ秒に1回より頻繁に更新すると仮定することは妥当と考えています。もちろん、整数のタイムスタンプをミリ秒未満の間隔で作成すると、すべてが一意であるとは限りません。

    なお、絶対値nanoTime()は任意です。絶対時間が必要な場合は、何らかの方法で調整します。つまり、起動時にそれをcurrentTimeMillis()と比較します。

    4

    私は下記の試み、それが異なる値を与えるたびに、おそらく、すべての時間一意であることが保証されていませんが、あなたはより良い精度のため

    System.nanoTime()を使用することができます。

    public static void main(String[] args) { 
         long time1 = System.nanoTime(); 
         long time2 = System.nanoTime(); 
         long time3 = System.nanoTime(); 
         System.out.println(time1); 
         System.out.println(time2); 
         System.out.println(time3); 
        } 
    

    もう一つの方法は、時間があなたのために重要ではなく、あなただけの固有の番号が必要な場合、これはおそらくbtterの選択肢であるユニークな番号についてAtomicInteger/AtomicLongクラスを使用することです。

    +2

    nanoTimeは単調ですが、必ずしも一意ではありません。あなたは重複をたくさん得ることができます。例えばRed Hat&Centos 5.xでは、分解能はマイクロ秒であるため、繰り返しの価値がたくさんあります。 –

    +0

    情報ありがとうございます。私はそれがOSとマシンに依存していると推測しました。 – fmucar

    +1

    nanoTimeを使用して、それとは異なるチェックをすることができます。 (私のソリューションに似ています)nanoTimeは、多くのシステムで稼働時間が秒単位で表示されます。 –

    1

    ソリューションを探している間、私は(汎用一意辞書順でソート可能な識別子) https://github.com/huxi/sulky/tree/master/sulky-ulid/

    それは長くはないが、短い ULIBに出くわしました次にUUID。

    A ULID:

    • はUUID/GUIDの 1と互換性があります。ミリ秒あたり21E + 24一意ULIDs
    • 辞書ソート
    • より良い効率と読みやすさのためにクロックフォードのbase32を使用
    • 36文字のUUIDとは対照的に、正準、26文字列として符号化された(5ビット(1,208,925,819,614,629,174,706,176は正確には)
    • )文字ごとに、それはせいぜい*を返すように)私はあなたが(*スロットリング*にcurrentTimeMillisを何を意味するのかはよく分からないん特殊文字(URL安全)
    関連する問題