自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

淺談Java中的幾種隨機(jī)數(shù)

開(kāi)發(fā) 后端
眾所周知,隨機(jī)數(shù)是任何一種編程語(yǔ)言最基本的特征之一。而生成隨機(jī)數(shù)的基本方式也是相同的:產(chǎn)生一個(gè)0到1之間的隨機(jī)數(shù)??此坪?jiǎn)單,但有時(shí)我們也會(huì)忽略了一些有趣的功能。

眾所周知,隨機(jī)數(shù)是任何一種編程語(yǔ)言最基本的特征之一。而生成隨機(jī)數(shù)的基本方式也是相同的:產(chǎn)生一個(gè)0到1之間的隨機(jī)數(shù)。看似簡(jiǎn)單,但有時(shí)我們也會(huì)忽略了一些有趣的功能。

我們從書(shū)本上學(xué)到什么?

最明顯的,也是直觀(guān)的方式,在Java中生成隨機(jī)數(shù)只要簡(jiǎn)單的調(diào)用:

  1. java.lang.Math.random() 

在所有其他語(yǔ)言中,生成隨機(jī)數(shù)就像是使用Math工具類(lèi),如abs, pow, floor, sqrt和其他數(shù)學(xué)函數(shù)。大多數(shù)人通過(guò)書(shū)籍、教程和課程來(lái)了解這個(gè)類(lèi)。一個(gè)簡(jiǎn)單的例子:從0.0到1.0之間可以生成一個(gè)雙精度浮點(diǎn)數(shù)。那么通過(guò)上面的信息,開(kāi)發(fā)人員要產(chǎn)生0.0和10.0之間的雙精度浮點(diǎn)數(shù)會(huì)這樣來(lái)寫(xiě):

  1. Math.random() * 10 

而產(chǎn)生0和10之間的整數(shù),則會(huì)寫(xiě)成:

  1. Math.round(Math.random() * 10

進(jìn)  階

通過(guò)閱讀Math.random()的源碼,或者干脆利用IDE的自動(dòng)完成功能,開(kāi)發(fā)人員可以很容易發(fā)現(xiàn),java.lang.Math.random()使用一個(gè)內(nèi)部的隨機(jī)生成對(duì)象 - 一個(gè)很強(qiáng)大的對(duì)象可以靈活的隨機(jī)產(chǎn)生:布爾值、所有數(shù)字類(lèi)型,甚至是高斯分布。例如:

  1. new java.util.Random().nextInt(10

它有一個(gè)缺點(diǎn),就是它是一個(gè)對(duì)象。它的方法必須是通過(guò)一個(gè)實(shí)例來(lái)調(diào)用,這意味著必須先調(diào)用它的構(gòu)造函數(shù)。如果在內(nèi)存充足的情況下,像上面的表達(dá)式是可以接受的;但內(nèi)存不足時(shí),就會(huì)帶來(lái)問(wèn)題。

一個(gè)簡(jiǎn)單的解決方案,可以避免每次需要生成一個(gè)隨機(jī)數(shù)時(shí)創(chuàng)建一個(gè)新實(shí)例,那就是使用一個(gè)靜態(tài)類(lèi)。猜你可能想到了java.lang.Math,很好,我們就是改良java.lang.Math的初始化。雖然這個(gè)工程量低,但你也要做一些簡(jiǎn)單的單元測(cè)試來(lái)確保其不會(huì)出錯(cuò)。

假設(shè)程序需要生成一個(gè)隨機(jī)數(shù)來(lái)存儲(chǔ),問(wèn)題就又來(lái)了。比如有時(shí)需要操作或保護(hù)種子(seed),一個(gè)內(nèi)部數(shù)用來(lái)存儲(chǔ)狀態(tài)和計(jì)算下一個(gè)隨機(jī)數(shù)。在這些特殊情況下,共用隨機(jī)生成對(duì)象是不合適的。

并  發(fā)

在Java EE多線(xiàn)程應(yīng)用程序的環(huán)境中,隨機(jī)生成實(shí)例對(duì)象仍然可以被存儲(chǔ)在類(lèi)或其他實(shí)現(xiàn)類(lèi),作為一個(gè)靜態(tài)屬性。幸運(yùn)的是,java.util.Random是線(xiàn)程安全的,所以不存在多個(gè)線(xiàn)程調(diào)用會(huì)破壞種子(seed)的風(fēng)險(xiǎn)。

另一個(gè)值得考慮的是多線(xiàn)程java.lang.ThreadLocal的實(shí)例。偷懶的做法是通過(guò)Java本身API實(shí)現(xiàn)單一實(shí)例,當(dāng)然你也可以確保每一個(gè)線(xiàn)程都有自己的一個(gè)實(shí)例對(duì)象。

雖然Java沒(méi)有提供一個(gè)很好的方法來(lái)管理java.util.Random的單一實(shí)例。但是,期待已久的Java 7提供了一種新的方式來(lái)產(chǎn)生隨機(jī)數(shù):

  1. java.util.concurrent.ThreadLocalRandom.current().nextInt(10

這個(gè)新的API綜合了其他兩種方法的優(yōu)點(diǎn):?jiǎn)我粚?shí)例/靜態(tài)訪(fǎng)問(wèn),就像Math.random()一樣靈活。ThreadLocalRandom也比其他任何處理高并發(fā)的方法要更快。
經(jīng)驗(yàn)

Chris Marasti-Georg 指出:

  1. Math.round(Math.random() * 10

使分布不平衡,例如:0.0 - 0.499999將四舍五入為0,而0.5至1.499999將四舍五入為1。那么如何使用舊式語(yǔ)法來(lái)實(shí)現(xiàn)正確的均衡分布,如下:

  1. Math.floor(Math.random() * 11) 

幸運(yùn)的是,如果我們使用java.util.Random或java.util.concurrent.ThreadLocalRandom就不用擔(dān)心上述問(wèn)題了。

Java實(shí)戰(zhàn)項(xiàng)目里面介紹了一些不正確使用java.util.Random API的危害。這個(gè)教訓(xùn)告訴我們不要使用:

  1. Math.abs(rnd.nextInt())%n 

而使用:

  1. rnd.nextInt(n) 

英文:http://www.summa-tech.com/blog/2012/03/14/the-several-flavors-of-random-in-java/

原文鏈接:http://www.oschina.net/question/157182_45274

【編輯推薦】

  1. Java編程中“為了性能”盡量要做的幾點(diǎn)
  2. 告別無(wú)止境的增刪改查:Java代碼生成器
  3. 使用JNI進(jìn)行混合編程:在Java中調(diào)用C/C++本地庫(kù)
  4. Java通過(guò)SSH2協(xié)議運(yùn)行遠(yuǎn)程程序
  5. Java Socket編程:初識(shí)TCP Socket
責(zé)任編輯:林師授 來(lái)源: 開(kāi)源中國(guó)社區(qū)
相關(guān)推薦

2011-07-08 15:11:03

JAVA

2019-09-11 10:09:00

Java虛擬機(jī)算法

2009-08-12 18:17:31

C#隨機(jī)數(shù)發(fā)生器

2015-10-13 10:00:58

Swift隨機(jī)數(shù)使用總結(jié)

2009-07-06 15:11:18

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

2021-06-01 22:31:57

區(qū)塊鏈隨機(jī)數(shù)技術(shù)

2023-01-03 07:49:45

Java隨機(jī)數(shù)線(xiàn)程

2010-09-06 17:40:59

SQL函數(shù)

2014-04-25 10:14:39

2009-06-11 15:16:18

不重復(fù)隨機(jī)數(shù)Java

2024-11-01 15:51:06

2021-12-27 09:31:20

HashtableJava隨機(jī)數(shù)

2025-01-17 00:00:00

Java隨機(jī)數(shù)服務(wù)

2024-01-25 11:32:21

2010-10-09 15:35:25

MySQL rand函

2010-03-22 19:41:31

2017-05-29 09:56:25

2014-05-13 10:21:00

2009-06-17 17:37:43

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

2009-12-08 11:44:14

PHP獲取隨機(jī)數(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)