欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談java隨機數(shù)的陷阱

 更新時間:2019年09月09日 15:02:07   作者:碼農(nóng)小胖哥  
這篇文章主要介紹了淺談java隨機數(shù)的陷阱,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

隨機數(shù)我們應(yīng)該不陌生,業(yè)務(wù)中我們用它來生成驗證碼,或者對重復(fù)性要求不高的id,甚至我們還用它在年會上搞抽獎。今天我們來探討一下這個東西。如果使用不當會引發(fā)一系列問題。

java中的隨機數(shù)

我們需要在Java中隨機生成一個數(shù)字。java開發(fā)中我們通常使用java.util.Random來搞,它提供了一種偽隨機的生成機制。Jvm 通過傳入的種子(seed)來確定生成隨機數(shù)的區(qū)間,只要種子一樣,獲取的隨機數(shù)的序列就是一致的。而且生成的結(jié)果都是可以預(yù)測的。是一種偽隨機數(shù)的實現(xiàn),而不是真正的隨機數(shù)。來確定使用的但是有些用例直接使用可能會導(dǎo)致一些意想不到的問題。Random的一個普遍用法:

// Random 實例
Random random = new Random();
//調(diào)用 nextInt() 方法 此外還有nextDouble(), nextBoolean(), nextFloat(), ...
random.nextInt();

或者,我們可以使用java中的數(shù)學(xué)計算類:

Math.random();

Math類只包含一個Random實例來生成隨機數(shù):

public static double random() {
 Random rnd = randomNumberGenerator;
 if (rnd == null) {
  // 返回一個新的Random實例
 rnd = initRNG();
 }
 return rnd.nextDouble();
 }

java.util.Random的用法是線程安全的。但是,在不同線程上并發(fā)使用相同的Random實例可能會導(dǎo)致爭用,從而導(dǎo)致性能不佳。其原因是使用所謂的種子來生成隨機數(shù)。種子是一個簡單的數(shù)字,它為生成新的隨機數(shù)提供了基礎(chǔ)。我們來看看Random中的next(int bits)方法:

protected int next(int bits) {
 long oldseed, nextseed;
 AtomicLong seed = this.seed;
 do {
  oldseed = seed.get();
  nextseed = (oldseed * multiplier addend) & mask;
 } while (!seed.compareAndSet(oldseed, nextseed));
 return (int)(nextseed >>> (48 - bits));}

首先,舊種子和新種子存儲在兩個輔助變量上。在這一點上,創(chuàng)造新種子的原則并不重要。要保存新種子,使用compareAndSet()方法將舊種子替換為下一個新種子,但這僅僅在舊種子對應(yīng)于當前設(shè)置的種子的條件下才會觸發(fā)。如果此時的值由并發(fā)線程操縱,則該方法返回false,這意味著舊值與例外值不匹配。因為是循環(huán)內(nèi)進行的操作,那么會發(fā)生自旋,直到變量與例外值匹配。這可能會導(dǎo)致性能不佳和線程競爭。

多線程下的隨機數(shù)

如果更多線程主動生成具有相同Random的實例的新隨機數(shù),則上述情況發(fā)生的概率越高。對于生成許多(非常多)隨機數(shù)的程序,不建議使用這種方式。在這種情況下,您應(yīng)該使用ThreadLocalRandom,它在1.7版本中添加到Java中。ThreadLocalRandom擴展了Random并添加選項以限制其使用到相應(yīng)的線程實例。為此,ThreadLocalRandom的實例保存在相應(yīng)線程的內(nèi)部映射中,并通過調(diào)用current()來返回對應(yīng)的Random。使用方式如下:

ThreadLocalRandom.current().nextInt()

安全的隨機數(shù)

通過對Random的一些分析我們可以知道Random事實上是偽隨機,是可以推導(dǎo)出規(guī)律的,而且依賴種子(seed)。如果我們搞抽獎或者其他一些對隨機數(shù)敏感的場景時,用Random就不合適了,容易被人鉆空子。JDK提供了SecureRandom來解決這個事情。

SecureRandom是強隨機數(shù)生成器,它可以產(chǎn)生高強度的隨機數(shù),產(chǎn)生高強度的隨機數(shù)依賴兩個重要的因素:種子和算法。算法是可以有很多的,通常如何選擇種子是非常關(guān)鍵的因素。 Random的種子是System.currentTimeMillis(),所以它的隨機數(shù)都是可預(yù)測的, 是弱偽隨機數(shù)。強偽隨機數(shù)的生成思路:收集計算機的各種信息,鍵盤輸入時間,內(nèi)存使用狀態(tài),硬盤空閑空間,IO延時,進程數(shù)量,線程數(shù)量等信息,CPU時鐘,來得到一個近似隨機的種子,主要是達到不可預(yù)測性。說的更通俗就是,使用加密算法生成很長的一個隨機種子,讓你無法猜測出種子,也就無法推導(dǎo)出隨機序列數(shù)。

總結(jié)

今天我們探討了業(yè)務(wù)中經(jīng)常使用的隨機數(shù)的一些機制和一些場景下的一些陷阱,希望你在使用隨機數(shù)的時候能避免這種陷阱。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

作者:碼農(nóng)小胖哥

來源:https://segmentfault.com/a/1190000020332761

相關(guān)文章

  • Java JDK1.5、1.6、1.7新特性整理

    Java JDK1.5、1.6、1.7新特性整理

    這篇文章主要介紹了Java JDK1.5、1.6、1.7新特性整理,需要的朋友可以參考下
    2016-10-10
  • Spring Cloud多個微服務(wù)之間調(diào)用代碼實例

    Spring Cloud多個微服務(wù)之間調(diào)用代碼實例

    這篇文章主要介紹了Spring Cloud多個微服務(wù)之間調(diào)用代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-12-12
  • SpringBoot實現(xiàn)單點登錄的實現(xiàn)詳解

    SpringBoot實現(xiàn)單點登錄的實現(xiàn)詳解

    在現(xiàn)代的Web應(yīng)用程序中,單點登錄(Single?Sign-On)已經(jīng)變得越來越流行,在本文中,我們將使用Spring?Boot構(gòu)建一個基本的單點登錄系統(tǒng),需要的可以參考一下
    2023-05-05
  • mybatisplus開啟sql打印的三種方式匯總

    mybatisplus開啟sql打印的三種方式匯總

    這篇文章主要介紹了mybatisplus開啟sql打印的三種方式,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2024-01-01
  • Java中的FileInputStream是否需要close問題

    Java中的FileInputStream是否需要close問題

    這篇文章主要介紹了Java中的FileInputStream是否需要close問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 創(chuàng)建Maven項目和Spring IOC實例過程解析

    創(chuàng)建Maven項目和Spring IOC實例過程解析

    這篇文章主要介紹了創(chuàng)建Maven項目和Spring IOC實例過程解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-12-12
  • Java中的Semaphore信號量使用解析

    Java中的Semaphore信號量使用解析

    這篇文章主要介紹了Java中的Semaphore信號量使用解析,Semaphore 通常我們叫它信號量,可以用來控制同時訪問特定資源的線程數(shù)量,通過協(xié)調(diào)各個線程,以保證合理的使用資源,需要的朋友可以參考下
    2023-11-11
  • 使用aop實現(xiàn)全局異常處理

    使用aop實現(xiàn)全局異常處理

    這篇文章主要為大家詳細介紹了使用aop實現(xiàn)全局異常處理,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • java實現(xiàn)的海盜算法優(yōu)化版

    java實現(xiàn)的海盜算法優(yōu)化版

    這篇文章主要介紹了java實現(xiàn)的海盜算法優(yōu)化版,結(jié)合實例形式分析了java海盜算法的具體實現(xiàn)技巧,需要的朋友可以參考下
    2017-07-07
  • 基于java類路徑classpath和包的實例講解

    基于java類路徑classpath和包的實例講解

    下面小編就為大家分享一篇基于java類路徑classpath和包的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01

最新評論