質問

概要:永続的なJava Webアプリケーションを開発しています。重複を防ぐために、永続化するすべてのリソースにグローバルに一意の識別子があることを確認する必要があります。

ファインプリント:

  1. RDBMSを使用していないため、派手なシーケンスジェネレーター(Oracleが提供するものなど)がありません
  2. 高速で、できればすべてメモリ内に保存したい-ファイルを開いて値を増やす必要はない
  3. スレッドセーフである必要があります(IDを生成するのに必要なJVMは一度に1つだけになると予想しています)
  4. JVMのインスタンス間で一貫性が必要です。サーバーがシャットダウンして起動した場合、IDジェネレーターは、以前のインスタンス化で生成したIDと同じIDを再生成するべきではありません(または少なくとも、本当に、本当にスリムである必要があります-何百万ものリソースが存在すると予想されます)
  5. EJBのユニークIDパターンの記事の例を見てきました。それらは私には機能しません(ミリ秒ごとに複数のリソースを保持するため、System.currentTimeMillis()だけに頼るのではなく)。
  6. 私は thisで提案された回答を見ました質問。それらについての私の懸念は、時間の経過とともに重複IDを取得する可能性があることです。 javaを使用する提案に興味があります。 UUID の場合は.util.UUID ですが、重複する可能性があります限りなく小さくする必要があります。
  7. JDK6を使用しています
役に立ちましたか?

解決

UUIDが<!> quot;十分<< >> quot;であることを確認してください。 340,282,366,920,938,463,463,374,607,431,770,000,000 UUIDが利用可能です。

http://www.wilybeagle.com/guid_store/guid_explain.htm

<!> quot;これらの数値を概観すると、met石に衝突する年間リスクは170億回に1回であると推定されます。つまり、確率は約0.00000000006(6 <!>#215; 10 <!>#8722; 11)、1年で数十兆個のUUIDを作成し、1つの複製を作成する確率に相当します。つまり、次の100年間にわたって毎秒10億UUIDを生成した後にのみ、1つの複製が作成される可能性は約50%になります。地球上のすべての人が6億のUUIDを所有している場合、1回の重複の可能性は約50%です。<!> quot;

http://en.wikipedia.org/wiki/Universally_Unique_Identifier

他のヒント

public class UniqueID {
    private static long startTime = System.currentTimeMillis();
    private static long id;

    public static synchronized String getUniqueID() {
        return "id." + startTime + "." + id++;
    }
}

PCごとに一意である必要がある場合:(System.currentTimeMillis() << 4) | (staticCounter++ & 15)などを使用できます。

これにより、1ミリ秒あたり16を生成できます。さらに必要な場合は、5シフトし、31でシフトします...

複数のPCで一意にする必要がある場合は、プライマリネットワークカードのMACアドレスも結合する必要があります。

編集:明確にする

private static int staticCounter=0;
private final int nBits=4;
public long getUnique() {
    return (currentTimeMillis() << nBits) | (staticCounter++ & 2^nBits-1);
}

nBitsをmsごとに生成する必要がある最大数の平方根に変更します。

最終的にロールオーバーします。おそらく20年か、nBitsが4の何か。

メモリから、RMIリモートパッケージにはUUIDジェネレータが含まれています。調査する価値があるかどうかはわかりません。

それらを生成しなければならなかった場合、通常は現在の日時のMD5ハッシュサム、ユーザー名、コンピューターのIPアドレスを使用します。基本的には、コンピューター/人について知ることができるすべてのものを取得し、この情報のMD5ハッシュを生成するという考え方です。

これは非常にうまく機能し、信じられないほど高速です(MessageDigestを初めて初期化した後)。

このようにしない理由

String id = Long.toString(System.currentTimeMillis()) + 
    (new Random()).nextInt(1000) + 
    (new Random()).nextInt(1000);

java UUIDが参照するより短くて高速な実装を使用する場合:

https://code.google.com/p/spf4j/source/browse/trunk/spf4j-core/src/main/java/org/spf4j/concurrent/UIDGenerator.java

javadocの実装の選択と制限を参照してください。

使用方法の単体テストは次のとおりです。

https://code.google.com/p/spf4j/source/browse/trunk/spf4j-core/src/test/java/org/spf4j/concurrent/UIDGeneratorTest.java

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top