16

Java で一意の 10 桁の ID を生成する必要があります。この ID の制限は次のとおりです。

  • 数値のみ
  • 最大10桁
  • 毎秒最大 10 個の異なる ID を作成可能
  • 一意である必要があります (アプリケーションが再起動した場合でも)
  • データベースに数値を保存できません
  • システムに多くの遅延を追加しないように、できるだけ速く

これまでに見つけた最良の解決策は次のとおりです。

private static int inc = 0;

private static long getId(){

    long id = Long.parseLong(String.valueOf(System.currentTimeMillis())
            .substring(1,10)
            .concat(String.valueOf(inc)));
    inc = (inc+1)%10;
    return id;
}

このソリューションには次の問題があります。

  • 何らかの理由で 1 秒あたり 10 個を超える ID を作成する必要がある場合、このソリューションは機能しません。
  • 約 32 年で、この ID が繰り返される可能性があります (これはおそらく許容されます)。

この ID を作成する他の解決策はありますか?

私が考えていない他の問題はありますか?

ご協力いただきありがとうございます、

4

4 に答える 4

10

これは小さな機能強化ですが、回復力があるはずです。

基本的に、最後の id 以降に刻んでいない場合を除き、現在の時刻をミリ秒単位で使用しますlast + 1

private static final long LIMIT = 10000000000L;
private static long last = 0;

public static long getID() {
  // 10 digits.
  long id = System.currentTimeMillis() % LIMIT;
  if ( id <= last ) {
    id = (last + 1) % LIMIT;
  }
  return last = id;
}

このままでは、比較的短いサイクル レートで 1 秒あたり 1000 まで処理できるはずです。サイクル レートを拡張する (ただし分解能を短くする) には、(System.currentTimeMillis() / 10) % 10000000000Lまたはを使用できます(System.currentTimeMillis() / 100) % 10000000000L

于 2013-08-14T09:37:49.437 に答える
1
private static AtomicReference<Long> currentTime = new AtomicReference<>(System.currentTimeMillis());

public static Long nextId() {
    return currentTime.accumulateAndGet(System.currentTimeMillis(), (prev, next) -> next > prev ? next : prev + 1) % 10000000000L;
}
于 2016-03-16T11:04:36.290 に答える
0

一意でなければならないということはどういう意味ですか? 現在実行中のインスタンス間でも? それはあなたの実装を壊します。

ユニバース全体で一意である必要がある場合、最善の解決策は、ユニバースごとに一意の値を生成するため、数学的に証明された識別子ジェネレータとして UUID を使用することです。精度の低い数値は衝突を引き起こします。

同時実行インスタンスが 1 つしかない場合、現在の時間をミリ単位で取得し、インクリメントを使用して 10 ミリ秒の問題を解決できます。数値の最後の位置の適切な数を犠牲にすると、1 ミリ秒以内に多くの数値を取得できます。精度を定義するよりも、1 秒あたりに必要な一意の数を意味します。このアプローチを使用すると、永続性なしで問題を解決できます。

于 2013-08-14T09:45:21.307 に答える