高い同時実行性の下で乱数を生成する方法

通常の開発では、我々は多くの場合、使用して乱数として、使用new Random()Math.random()などが、上記の方法を使用して(電子商取引事業、ミドルウェアシステムなど)の高同時実行環境では最適ではなく、システムのパフォーマンスに影響を与えます。では、同時実行性の高い環境で乱数を生成するにはどうすればよいでしょうか。

乱数を使用して乱数を生成する

@Test
public void testRandom() {
    for (int i = 0; i < 10; i++) {
        double random = Math.random();
        System.out.println(random);
    }
}

試験結果:

0.5036752695751798
0.6386142116701573
0.9884333194038111
0.9582700780194423
0.5868131855429274
0.4641415198964046
0.003620726435900945
0.3840115367892679
0.5840416616384468
0.2752130416815357

ランダムのソースコード:

public static double random() {
    return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
}
private static final class RandomNumberGeneratorHolder {
    static final Random randomNumberGenerator = new Random();
}

CASは最下層で使用されます

画像

スレッドが新しい乱数を取得するには、次の2つのことを行う必要があります。

「「
  1. 古いシードに基づいて新しいシードを生成します

  2. 新しいシードから乱数を生成します

画像

マルチスレッドでは、各スレッドが同じseedなるのを防ぐためにRandomAtomicLong CAS(比較および設定)操作を使用してスレッドを更新しseedます。上記のコードを見ると、スレッドCASが失敗した場合、ここでスピンします(ループで再試行します)。これがシード上の複数のスレッド間の競合です。システムリソースを占有します。

ThreadLocalRandomを使用して乱数を生成します

java.util.concurrent以下を使用して、高い同時実行性でThreadLocalRandom乱数生成ます。

public static void main(String[] args){
    new RandomTest().testThreadLocalRandom();
}

public void testThreadLocalRandom() {
    for (int i = 0; i < 3 ; i++) {
        new Thread(() -> System.out
                .println(Thread.currentThread().getName() + ": " +
                        ThreadLocalRandom.current().nextDouble())).start();
    }
}

Javaコードのテスト結果:

Thread-0: 0.24025397109614877
Thread-2: 0.1704942948906747
Thread-1: 0.6864282829219596

ThreadLocalRandom.current()メソッドを見てみましょう

画像

current()このメソッドは静的メソッドであるため、複数のスレッドが生成するのは1つだけThreadLocalRandom实例です。

画像

乱数

画像

current()メソッドを呼び出すとき、現在のスレッドが初期化されていない場合、最初に初期化seed(呼び出されlocalInit())され、現在のスレッド情報と対応する情報がメソッドにseed保存されUNSAFEます。UNSAFEメソッドはすべてローカルメソッドであり、オペレーティングシステム関連のメソッドを呼び出すため、ここでは説明しません。

ここで、各スレッドを呼び出す必要があることに注意してくださいThreadLocalRandom.current()

画像

TheadLocalRandomCASが使用されていないことわかりましたこれが、それによって生成される乱数が速い理由です。

を使用するとTheadLocalRandom、各スレッドは独自のを維持seedするため、複数のスレッドが同じシードリソースをめぐって競合することはありません。

インターネット上の誰かTheadLocalRandomによってテストされたパフォーマンス、ランダムよりも8〜10倍高速です。

したがって、同時実行性が高い場合は、ThreadLocalRandom乱数生成を使用します

 

過去におすすめ

QRコードをスキャンして、よりエキサイティングになります。または、WeChatLvshen_9を検索すると、返信してバックグラウンドで情報を取得できます

  1. 回复"java" 获取java电子书;

  2. 回复"python"获取python电子书;

  3. 回复"算法"获取算法电子书;

  4. 回复"大数据"获取大数据电子书;

  5. 回复"spring"获取SpringBoot的学习视频。

  6. 回复"面试"获取一线大厂面试资料

  7. 回复"进阶之路"获取Java进阶之路的思维导图

  8. 回复"手册"获取阿里巴巴Java开发手册(嵩山终极版)

  9. 回复"总结"获取Java后端面试经验总结PDF版

  10. 回复"Redis"获取Redis命令手册,和Redis专项面试习题(PDF)

  11. 回复"并发导图"获取Java并发编程思维导图(xmind终极版)

もう1つ:[マイベネフィット]をクリックして、さらに驚きを持ってください。

おすすめ

転載: blog.csdn.net/wujialv/article/details/111879670