多くのサーブレット リクエストに対して乱数を生成したいと考えています。問題は、各サーブレットで新しい Random オブジェクトを使用すると、全体的な確率が正しくなくなることです。
たとえば、約 10000 件以上のリクエストがある場合、すべてのランダム値が範囲内で均等に分散されるはずです。
多くのサーブレット リクエストに対して乱数を生成したいと考えています。問題は、各サーブレットで新しい Random オブジェクトを使用すると、全体的な確率が正しくなくなることです。
たとえば、約 10000 件以上のリクエストがある場合、すべてのランダム値が範囲内で均等に分散されるはずです。
では、なぜグローバルRandom
インスタンスを使用しないのでしょうか。
または、ThreadLocalRandom
どちらが高速かを使用できます。また、インスタンスを実際に作成できないため、一種のグローバルです。を呼び出してインスタンスを取得できますThreadLocalRandom.current()
。Java 7 では、スレッドごとのインスタンスを返します。Java 8 ではさらに最適化され、常に同じシングルトンを返します。
Random を使用して本当にランダムなシーケンスを取得するのは少し複雑です。Random は 2^48 周期の LCG ベースであり、シードには十分注意する必要があります。現在の値を維持するために DataStore を使用して単一のシーケンスを生成する方法がありますが、新しい乱数を生成するたびに値を更新する必要があるため、パフォーマンスはあまり良くありません。これは、memcahce を使用しない場合でも 10 ~ 20 リクエスト/秒、memcache を使用するとおそらく 100 リクエスト/秒に到達できることを意味します。原子シード値を保持する必要があるため、シャーディングはあまり役に立ちません。
アルゴリズムは次のようになります。
次のすべてのリクエストで(操作全体が単一のトランザクションにある必要があります):
4.1. DataStore からシードを読み取る
4.2. シードを使用して新しいランダムを作成します。
4.3. 新しい int を生成します。
4.4. シードを設定 = ランダム <<< 16
4.5. シードをデータストアに保存