0

多くのサーブレット リクエストに対して乱数を生成したいと考えています。問題は、各サーブレットで新しい Random オブジェクトを使用すると、全体的な確率が正しくなくなることです。

たとえば、約 10000 件以上のリクエストがある場合、すべてのランダム値が範囲内で均等に分散されるはずです。

4

2 に答える 2

2

では、なぜグローバルRandomインスタンスを使用しないのでしょうか。

または、ThreadLocalRandomどちらが高速かを使用できます。また、インスタンスを実際に作成できないため、一種のグローバルです。を呼び出してインスタンスを取得できますThreadLocalRandom.current()。Java 7 では、スレッドごとのインスタンスを返します。Java 8 ではさらに最適化され、常に同じシングルトンを返します。

于 2013-02-19T04:13:18.517 に答える
0

Random を使用して本当にランダムなシーケンスを取得するのは少し複雑です。Random は 2^48 周期の LCG ベースであり、シードには十分注意する必要があります。現在の値を維持するために DataStore を使用して単一のシーケンスを生成する方法がありますが、新しい乱数を生成するたびに値を更新する必要があるため、パフォーマンスはあまり良くありません。これは、memcahce を使用しない場合でも 10 ~ 20 リクエスト/秒、memcache を使用するとおそらく 100 リクエスト/秒に到達できることを意味します。原子シード値を保持する必要があるため、シャーディングはあまり役に立ちません。

アルゴリズムは次のようになります。

  1. 最初の整数を生成します (long を使用するには、追加の処理が必要になります。int を生成する方がはるかに簡単です)。
  2. シードを設定 = ランダム <<< 16
  3. シードを DataStore に保存します (トランザクションを忘れないでください)
  4. 次のすべてのリクエストで(操作全体が単一のトランザクションにある必要があります):

    4.1. DataStore からシードを読み取る

    4.2. シードを使用して新しいランダムを作成します。

    4.3. 新しい int を生成します。

    4.4. シードを設定 = ランダム <<< 16

    4.5. シードをデータストアに保存

于 2013-02-19T18:53:19.633 に答える