溫馨提示×

溫馨提示×

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

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

Java隨機(jī)數(shù)以及多線程下的隨機(jī)數(shù)用法

發(fā)布時間:2021-09-04 18:32:32 來源:億速云 閱讀:244 作者:chen 欄目:編程語言

本篇內(nèi)容主要講解“Java隨機(jī)數(shù)以及多線程下的隨機(jī)數(shù)用法”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Java隨機(jī)數(shù)以及多線程下的隨機(jī)數(shù)用法”吧!

Java中的隨機(jī)數(shù)

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

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

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

Math.random();

Math類只包含一個Random實例來生成隨機(jī)數(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)致性能不佳。其原因是使用所謂的種子來生成隨機(jī)數(shù)。種子是一個簡單的數(shù)字,它為生成新的隨機(jī)數(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)于當(dāng)前設(shè)置的種子的條件下才會觸發(fā)。如果此時的值由并發(fā)線程操縱,則該方法返回false,這意味著舊值與例外值不匹配。因為是循環(huán)內(nèi)進(jìn)行的操作,那么會發(fā)生自旋,直到變量與例外值匹配。這可能會導(dǎo)致性能不佳和線程競爭。

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

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

ThreadLocalRandom.current().nextInt()

安全的隨機(jī)數(shù)

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

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

到此,相信大家對“Java隨機(jī)數(shù)以及多線程下的隨機(jī)數(shù)用法”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI