最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

你知道jdk竟有4個(gè)random嗎

 更新時(shí)間:2021年06月16日 10:16:31   作者:小姐姐味道  
這篇文章主要給大家介紹了關(guān)于jdk中4個(gè)random的相關(guān)資料,分別是Random、ThreadLocalRandom、SecureRandom以及SplittableRandom,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

我們從jdk8說(shuō)起。主要是四個(gè)隨機(jī)數(shù)生成器。神馬?有四個(gè)?

接下來(lái)我們簡(jiǎn)單說(shuō)下這幾個(gè)類的使用場(chǎng)景,來(lái)了解其中的細(xì)微差別,和api設(shè)計(jì)者的良苦用心。

java.util.Randomjava.util.concurrent.ThreadLocalRandomjava.security.SecureRandomjava.util.SplittableRandom

Random

最常用的就是Random。

用來(lái)生成偽隨機(jī)數(shù),默認(rèn)使用48位種子、線性同余公式進(jìn)行修改。我們可以通過(guò)構(gòu)造器傳入初始seed,或者通過(guò)setSeed重置(同步)。默認(rèn)seed為系統(tǒng)時(shí)間的納秒數(shù),真大!

如果兩個(gè)(多個(gè))不同的Random實(shí)例,使用相同的seed,按照相同的順序調(diào)用相同方法,那么它們得到的數(shù)字序列也是相同的。這看起來(lái)不太隨機(jī)。  這種設(shè)計(jì)策略,既有優(yōu)點(diǎn)也有缺點(diǎn),優(yōu)點(diǎn)是“相同seed”生成的序列是一致的,使過(guò)程具有可回溯和校驗(yàn)性(平臺(tái)無(wú)關(guān)、運(yùn)行時(shí)機(jī)無(wú)關(guān));缺點(diǎn)就是,這種一致性,潛在引入其“可被預(yù)測(cè)”的風(fēng)險(xiǎn)。

Random的實(shí)例是線程安全的。  但是,跨線程并發(fā)使用相同的java.util.Random實(shí)例可能會(huì)遇到爭(zhēng)用,從而導(dǎo)致性能稍欠佳(nextX方法中,在對(duì)seed賦值時(shí)使用了CAS,測(cè)試結(jié)果顯示,其實(shí)性能損耗很?。U?qǐng)考慮在多線程設(shè)計(jì)中使用ThreadLocalRandom。同時(shí),我們?cè)诓l(fā)環(huán)境下,也沒有必要刻意使用多個(gè)Random實(shí)例。

Random實(shí)例不具有加密安全性。  相反,請(qǐng)考慮使用SecureRandom來(lái)獲取加密安全的偽隨機(jī)數(shù)生成器,以供安全敏感應(yīng)用程序使用。

Random是最常用的隨機(jī)數(shù)生成類,適用于絕大部分場(chǎng)景。

Random random = new Random(100);System.out.println(random.nextInt(10) + "," + random.nextInt(30) + "," + random.nextInt(50));random = new Random(100);System.out.println(random.nextInt(10) + "," + random.nextInt(30) + "," + random.nextInt(50));random = new Random(100);System.out.println(random.nextInt(10) + "," + random.nextInt(30) + "," + random.nextInt(50));

上述三個(gè)不同的random實(shí)例,使用了相同的seed。調(diào)用過(guò)程一樣,其中產(chǎn)生的隨機(jī)數(shù)序列也是完全一樣的。多次執(zhí)行結(jié)果也完全一致,簡(jiǎn)單而言,只要初始seed一樣,即使實(shí)例不同,多次運(yùn)行它們的結(jié)果都是一致的。這個(gè)現(xiàn)象與上面所說(shuō)的一致。

如果Random構(gòu)造器中不指定seed,而是使用默認(rèn)的系統(tǒng)時(shí)間納秒數(shù)作為主導(dǎo)變量,三個(gè)random實(shí)例執(zhí)行的結(jié)果是不同的。多次執(zhí)行結(jié)果也不一樣。由此可見,seed是否具有隨機(jī)性,在一定程度上,也決定了Random產(chǎn)生結(jié)果的隨機(jī)性。

所以,在分布式或者多線程環(huán)境下,如果Random實(shí)例處于代碼一致的tasks線程中,可能這些分布式進(jìn)程或者線程,產(chǎn)出的序列值是一樣的。這也是在JDK 7引入ForkJoin的同時(shí),也引入了ThreadLocalRandom類。

ThreadLocalRandom

這個(gè)類的作用,使得隨機(jī)數(shù)的生成器隔離到當(dāng)前線程。此類繼承自java.util.Random,與Math類使用的全局Random生成器一樣,ThreadLocalRandom使用內(nèi)部生成的種子進(jìn)行初始化,否則可能無(wú)法修改。

在并發(fā)程序中使用ThreadLocalRandom,通常會(huì)有更少的開銷和競(jìng)爭(zhēng)。當(dāng)多個(gè)任務(wù)(例如,每個(gè)ForkJoinTask)在線程池中并行使用隨機(jī)數(shù)時(shí),ThreadLocalRandom是特別合適的。

切記,在多個(gè)線程中不應(yīng)該共享ThreadLocalRandom實(shí)例。

ThreadLocalRandom初始化是private的,所以無(wú)法通過(guò)構(gòu)造器設(shè)定seed,此外其setSeed方法也被重寫而不支持(拋出異常)。默認(rèn)情況下,每個(gè)ThreadLocalRandom實(shí)例的seed主導(dǎo)變量值為系統(tǒng)時(shí)間(納秒):

private static long initialSeed() {    String sec = VM.getSavedProperty("java.util.secureRandomSeed");    if (Boolean.parseBoolean(sec)) {        byte[] seedBytes = java.security.SecureRandom.getSeed(8);        long s = (long)(seedBytes[0]) & 0xffL;        for (int i = 1; i < 8; ++i)            s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);        return s;    }    return (mix64(System.currentTimeMillis()) ^            mix64(System.nanoTime()));}

根據(jù)其初始化seed的實(shí)現(xiàn),我們也可以通過(guò)JVM啟動(dòng)參數(shù)增加“-Djava.util.secureRandomSeed=true”,此時(shí)初始seed變量將不再是系統(tǒng)時(shí)間,而是由SecureRandom類生成一個(gè)隨機(jī)因子,以此作為ThreadLoalRandom的初始seed。

真是夠繞的。

從源碼中,我并沒有看到Thread-ID作為變量生成seed,而且nextX方法中隨機(jī)數(shù)生成算法也具有一致性。這意味著,如果多個(gè)線程初始ThreadLocalRandom的時(shí)間完全一致,在調(diào)用方法和過(guò)程相同的情況下,產(chǎn)生的隨機(jī)序列也是相同的;在一定程度上“-Djava.util.secureRandom=true”可以規(guī)避此問(wèn)題。

ThreadLocalRandom并沒有使用ThreadLocal來(lái)支持內(nèi)部數(shù)據(jù)存儲(chǔ)等,而是直接使用UnSafe操作當(dāng)前Thread對(duì)象引用中seed屬性的內(nèi)存地址并進(jìn)行數(shù)據(jù)操作,我比較佩服SUN的這種巧妙的做法。

SecureRandom

它也繼承自Random,該類提供加密強(qiáng)隨機(jī)數(shù)生成器(RNG),加密強(qiáng)隨機(jī)數(shù)最低限度符合FIPS 140-2“加密模塊的安全要求”。此外,SecureRandom必須產(chǎn)生非確定性輸出。因此,傳遞給SecureRandom對(duì)象的任何種子材料必須是不可預(yù)測(cè)的,并且所有SecureRandom輸出序列必須具有加密強(qiáng)度。(官文,其實(shí)我也一知半解)

SecureRandom默認(rèn)支持兩種RNG加密算法實(shí)現(xiàn):

”SHA1PRNG”算法提供者sun.security.provider.SecureRandom

”NativePRNG”提供者sun.security.provider.NativePRNG

默認(rèn)情況下,是“SHA1PRNG”,即SUN提供的實(shí)現(xiàn)。此外可以通過(guò)

“-Djava.security=file:/dev/urandom”

(推薦)或者

“-Djava.security=file:/dev/random”

指定使用linux本地的隨機(jī)算法,

即NativePRNG;

其中“/dev/random”與“/dev/urandom”在不同unix-*平臺(tái)中實(shí)現(xiàn)有所不同,性能也有所差異,建議使用“/dev/urandom”。

/dev/random的一個(gè)副本是/dev/urandom (”unlocked”,非阻塞的隨機(jī)數(shù)發(fā)生器),它會(huì)重復(fù)使用熵池中的數(shù)據(jù)以產(chǎn)生偽隨機(jī)數(shù)據(jù)。這表示對(duì)/dev/urandom的讀取操作不會(huì)產(chǎn)生阻塞,但其輸出的熵可能小于/dev/random的。它可以作為生成較低強(qiáng)度密碼的偽隨機(jī)數(shù)生成器,不建議用于生成高強(qiáng)度長(zhǎng)期密碼。

算法的內(nèi)部實(shí)現(xiàn),比較復(fù)雜;本人測(cè)試,其實(shí)性能差不不太大(JDK 8環(huán)境)。SecureRandom也是線程安全的。

從輸出結(jié)果上分析,無(wú)論是否指定SecureRandom的初始seed,單個(gè)實(shí)例多次運(yùn)行的結(jié)果也完全不同 ;多個(gè)不同的SecureRandom實(shí)例無(wú)論是否指定seed,即使指定一樣的初始seed,同時(shí)運(yùn)行的結(jié)果也完全不同。

SecureRandom繼承自Random,但是對(duì)nextX方法中的底層方法進(jìn)行的重寫覆蓋,不過(guò)仍然基于Random的CAS且SecureRandom的底層方法還使用的同步,所以在并發(fā)環(huán)境下,性能比Random差了一些。

SplittableRandom

JDK 8 新增的API,主要適用于Fork/join形式的跨線程操作中。它并沒有繼承java.util.Random類。

具有相同seed的不同SplittableRandom實(shí)例或者同一個(gè)SplittableRandom,多次運(yùn)行結(jié)果是一致的。這和Random是一致的。

非線程安全,不能被并發(fā)使用。 (不會(huì)報(bào)錯(cuò),但是并發(fā)時(shí)可能多個(gè)線程同時(shí)得到相同的隨機(jī)數(shù))

同ThreadLocalRandom,對(duì)“-Djava.util.secureRandom=true”參數(shù)支持,但是只有使用默認(rèn)構(gòu)造器的時(shí)候,才會(huì)使用SecureRandom輔助生成初始seed。即不指定初始seed時(shí),同一個(gè)SplittableRandom實(shí)例多次運(yùn)行,或者不同的實(shí)例運(yùn)行,結(jié)果是不同的。

其中有一個(gè)split()方法,用來(lái)構(gòu)造并返回與新的實(shí)例,這個(gè)實(shí)例共享了一些不可變狀態(tài)。需要注意,split產(chǎn)生的新SplittableRandom實(shí)例,與原實(shí)例并不存在內(nèi)部數(shù)據(jù)的并發(fā)競(jìng)爭(zhēng),也不會(huì)交替或者延續(xù)原實(shí)例的隨機(jī)數(shù)生成序列(即兩個(gè)實(shí)例產(chǎn)出隨機(jī)序列的一致性,與原實(shí)例沒有關(guān)系,只是在統(tǒng)計(jì)值層面更加接近);但是代碼一致性的情況下,多次運(yùn)行,其隨機(jī)數(shù)序列的結(jié)果總是一致的(假如初始seed是指定的,而非默認(rèn)),這一點(diǎn)與Random、ThreadLocalRandom表現(xiàn)相同。

public SplittableRandom split() {    return new SplittableRandom(nextLong(), mixGamma(nextSeed()));}

樣例代碼。

System.out.println("第一段");SplittableRandom random = new SplittableRandom(100);Thread thread = new Thread(new Runnable() {    @Override    public void run() {        SplittableRandom _random = random.split();        for (int i=0; i < 5; i++) {            System.out.println("---" + _random.nextInt(100));        }    }});thread.start();thread.join();for (int i=0; i < 5; i++) {    System.out.println("+++" + random.nextInt(100));}System.out.println("第二段");SplittableRandom _random = new SplittableRandom(100);for (int i=0; i < 10; i++) {    System.out.println("..." + _random.nextInt(100));}

執(zhí)行結(jié)果。

第一段---71---85---10---60---98+++44+++87+++77+++67+++72第二段...92...30...44...87...77...67...72...23...9...64

從執(zhí)行結(jié)果上看,split產(chǎn)生的random實(shí)例與原實(shí)例執(zhí)行結(jié)果上沒有相似之處;但是不同SplittableRandom實(shí)例(無(wú)論是否執(zhí)行過(guò)split),其產(chǎn)出隨機(jī)數(shù)序列是一致的。

性能檢測(cè)

簡(jiǎn)析,基準(zhǔn):100000隨機(jī)數(shù),單線程

1、 Random :2毫秒

2、 ThreadLocalRandom :1毫秒

3、 SecureRandom

1)默認(rèn)算法,即SHAR1PRNG:80毫秒左右。
2)NativePRNG:90毫秒左右。

4、 SplittableRandom :1毫秒

End

平常使用Random,或者大多數(shù)時(shí)候使用,都是沒有問(wèn)題的,它也是線程安全的。SplittableRandom是內(nèi)部使用的類,應(yīng)用較少,即使它也是public的也掩飾不了偏門。ThreadLocalRandom是為了在高并發(fā)環(huán)境下節(jié)省一點(diǎn)細(xì)微的時(shí)間,追求性能的應(yīng)用推薦使用。而對(duì)于有安全需求的,又希望更隨機(jī)一些的,用SecureRandom再好不過(guò)了。

jdk竟然有這么多隨機(jī)數(shù)生成器。有沒有大吃一精?我反正是跪了。

到此這篇關(guān)于jdk竟有4個(gè)random的文章就介紹到這了,更多相關(guān)jdk有4個(gè)random內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Jenkins任務(wù)批量修改的技巧分享

    Jenkins任務(wù)批量修改的技巧分享

    這篇文章主要給大家介紹了關(guān)于Jenkins任務(wù)批量修改的一些技巧,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Java實(shí)現(xiàn)餐廳點(diǎn)餐系統(tǒng)的實(shí)例代碼

    Java實(shí)現(xiàn)餐廳點(diǎn)餐系統(tǒng)的實(shí)例代碼

    這篇文章主要介紹了Java實(shí)現(xiàn)餐廳點(diǎn)餐系統(tǒng),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-06-06
  • java排序算法圖文詳解

    java排序算法圖文詳解

    這篇文章主要為大家詳細(xì)介紹了Java經(jīng)典排序算法之歸并排序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望可以對(duì)你有所幫助
    2021-07-07
  • Java實(shí)現(xiàn)的RSA加密解密算法示例

    Java實(shí)現(xiàn)的RSA加密解密算法示例

    這篇文章主要介紹了Java實(shí)現(xiàn)的RSA加密解密算法,結(jié)合實(shí)例形式分析了java RAS加密解密算法的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2018-01-01
  • RxJava2 Scheduler使用實(shí)例深入解析

    RxJava2 Scheduler使用實(shí)例深入解析

    這篇文章主要為大家介紹了RxJava2 Scheduler使用實(shí)例深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • JMagick實(shí)現(xiàn)基本圖像處理的類實(shí)例

    JMagick實(shí)現(xiàn)基本圖像處理的類實(shí)例

    這篇文章主要介紹了JMagick實(shí)現(xiàn)基本圖像處理的類,實(shí)例分析了java圖像處理的相關(guān)技巧,需要的朋友可以參考下
    2015-06-06
  • Java實(shí)現(xiàn)本地緩存的方式匯總

    Java實(shí)現(xiàn)本地緩存的方式匯總

    引入緩存,主要用于實(shí)現(xiàn)系統(tǒng)的高性能,高并發(fā),這篇文章主要介紹了Java實(shí)現(xiàn)本地緩存的幾種方式,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • Java多態(tài)性抽象類與接口細(xì)致詳解

    Java多態(tài)性抽象類與接口細(xì)致詳解

    這篇文章主要給大家介紹了關(guān)于Java中方法使用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • Mybatisplus主鍵生成策略算法解析

    Mybatisplus主鍵生成策略算法解析

    這篇文章主要介紹了Mybatisplus主鍵生成策略算法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • spring Roo安裝使用簡(jiǎn)介

    spring Roo安裝使用簡(jiǎn)介

    這篇文章主要介紹了spring Roo安裝使用簡(jiǎn)介,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2017-12-12

最新評(píng)論

师宗县| 肇庆市| 漯河市| 延寿县| 德令哈市| 禹州市| 甘泉县| 林州市| 重庆市| 托克逊县| 大丰市| 平阳县| 同心县| 壤塘县| 九江市| 湟源县| 甘肃省| 郎溪县| 巩留县| 临沂市| 慈利县| 新密市| 巢湖市| 巴中市| 乌拉特中旗| 思茅市| 休宁县| 固阳县| 白水县| 象山县| 夏邑县| 乌拉特中旗| 盐亭县| 义乌市| 四川省| 金平| 平安县| 沽源县| 古蔺县| 六盘水市| 崇阳县|