91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java生成隨機數的幾種常見方式

發布時間:2020-05-29 16:38:39 來源:億速云 閱讀:205 作者:鴿子 欄目:編程語言

我們來說說Java常見的生成隨機數的幾種方式:Random,ThreadLocalRandom,SecureRandom;其實產生隨機數有很多種方式但我們常見的就這幾種,如果需要詳細了解這個三個類,可以查看JAVA API.

Random random = new Random();  
int a = random.nextInt(5);//隨機生成0~4中間的數字
其實Random是有構造函數的,他的參數可以傳一個long類型的值,當使用空的構造的時候,使用的實際上是System.nanoTime()也就是當前時間毫秒數的值,我們把這個叫做 種子 。

種子是干什么的呢,實際上我們生成的隨機數都是偽隨機數,而想要使我們生成的隨機數強度更高,就需要更好的 算法 和種子。一般情況下,要使用Random去生成隨機數,直接用空構造函數就可以了。那么這個種子到底有什么用呢,實際上讀者去試驗一下就知道了,我們使用固定隨機數,比如1,然后我們連續次去new這個Random,然后去生成一個隨機數,像下面這樣,你會發現,三個數的結果是一樣的。

/**
 * -1157793070
 * 1913984760
 * 1107254586
 */
@Test
public void test2(){
    Random random = new Random(10); 
    for (int i = 0; i < 3; i++){
        System.out.println(random.nextInt());
    }
}

所以我們一定不能把這個種子寫死,用當前時間毫秒數,還是比較好些。另外,使用Random盡量不要重復new對象,其實也沒什么意義的。最后說一點,Random是線程安全的,去 這里 的官方文檔可以看到,“Instances of java.util.Random are threadsafe.”。但是在 多線程的表現中,他的性能很差。

在Java的API幫助文檔中,總結了一下對這個Random的描述:

java.util.Random類中實現的隨機算法是偽隨機,也就是有規則的隨機,所謂有規則的就是在給定種(seed)的區間內隨機生成數字;
相同種子數的Random對象,相同次數生成的隨機數字是完全相同的;

Random類中各方法生成的隨機數字都是均勻分布的,也就是說區間內部的數字生成的幾率均等;

這個類是Java7新增的類,給多線程并發生成隨機數使用的。為什么ThreadLocalRandom要比Random快呢,這是因為Random在生成隨機數的時候使用了CAS(compare and set),但是ThreadLocalRandom卻沒有使用。

下面是java.util.Random的生成隨機數的方法:

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));
}
而這邊的seed是一個全局變量:

/**

  • The internal state associated with this pseudorandom number generator.
  • (The specs for the methods in this class describe the ongoing
  • computation of this value.)
    */
    private final AtomicLong seed;
    多個線程同時獲取隨機數的時候,會競爭同一個seed,導致了效率的降低。

可見,其中通過CAS方式保證其線程安全性。這在高并發的環境中由于線程間的競爭必然帶來一定的性能損耗。

ThreadLocal此時就派上用場了,ThreadLocalRandom是通過ThreadLocal改進的用于隨機數生成的工具類,每個線程單獨持有一個ThreadLocalRandom對象引用,這就完全杜絕了線程間的競爭問題。

另外ThreadLocalRandom的實例化比較特別,下面簡單舉例一下。

ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();  
int a  = threadLocalRandom.nextInt(5);  
由于是和線程綁定的,所以他也是從當前線程獲取的。

在需要頻繁生成隨機數,或者安全要求較高的時候,不要使用Random,這個很好理解吧,從我們最開始的介紹中可以知道,Random生成的值其實是可以預測的。

內置兩種隨機數算法,NativePRNG和SHA1PRNG,看實例化的方法了。通過new來初始化,默認來說會使用NativePRNG算法生成隨機數,但是也可以配置-Djava.security參數來修改調用的算法。如果是/dev/[u]random兩者之一就是NativePRNG,否則就是SHA1PRNG。

在 jvm 啟動參數這樣加就好了,-Djava.security=file:/dev/urandom。

當然還可以通過getInstance來初始化對象,有一個參數的,直接傳一個算法名就行,如果不存在算法拋異常;另外有兩個參數的,第二個參數還可以指定算法程序包。下面來看下實現代碼。

SecureRandom secureRandom = new SecureRandom();
SecureRandom secureRandom3 = SecureRandom.getInstance("SHA1PRNG");
SecureRandom secureRandom2 = SecureRandom.getInstance("SHA1PRNG", "SUN");
當然我們使用這個類去生成隨機數的時候,一樣只需要生成一個實例每次去生成隨機數就好了,也沒必要每次都重新生成對象。另外,這個類生成隨機數,首次調用性能比較差,如果條件允許最好服務啟動后先調用一下nextInt()。

另外,實際上SHA1PRNG的性能將近要比NativePRNG的性能好一倍,synchronized的代碼少了一半,所以沒有特別重的安

全需要,盡量使用SHA1PRNG算法生成隨機數。

這也是個比較常用的生成隨機數的方式,默認生成0~1之間的小數.

總結:

1、單機中如果對安全性要求不高的情況下,使用 Random;對安全性要求高,就用 SecureRandom;

SecureRandom里有兩種算法,SHA1PRNG 和 NativePRNG,SHA1PRNG的性能好,但是NativePRNG的安全性高。

2、Random 是線程安全的,用CAS來保持,但是性能比不高,所以多線程中,盡量使用 java并發包里的 ThreadLocalRandom,

避免了線程之間的競爭導致的性能問題

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

昌平区| 福建省| 额敏县| 宜川县| 启东市| 永和县| 保定市| 曲靖市| 马山县| 汶上县| 河北省| 武威市| 兴安盟| 贵港市| 二连浩特市| 济阳县| 济南市| 云龙县| 西藏| 肇庆市| 白银市| 渭南市| 乌拉特后旗| 延庆县| 额尔古纳市| 分宜县| 丹江口市| 金山区| 湘乡市| 年辖:市辖区| 台安县| 安图县| 阜宁县| 永嘉县| 临汾市| 河津市| 江城| 子长县| 兴安县| 大连市| 靖远县|