<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    甜咖啡

    我的IT空間

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

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

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

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

    1. java.lang.Math.random() 

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

    1. Math.random() * 10 

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

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

    進(jìn)階

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

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

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

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

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

    并發(fā)

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

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

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

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

    這個(gè)新的API綜合了其他兩種方法的優(yōu)點(diǎn):?jiǎn)我粚?shí)例/靜態(tài)訪問,就像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。那么如何使用舊式語法來實(shí)現(xiàn)正確的均衡分布,如下:

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

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

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

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

    而使用:

    1. rnd.nextInt(n) 

    posted on 2012-04-16 10:01 甜咖啡 閱讀(183) 評(píng)論(0)  編輯  收藏


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     

    導(dǎo)航

    <2012年4月>
    25262728293031
    1234567
    891011121314
    15161718192021
    22232425262728
    293012345

    統(tǒng)計(jì)

    常用鏈接

    留言簿(1)

    我參與的團(tuán)隊(duì)

    隨筆檔案

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 久久亚洲精品成人无码网站| 久久精品国产亚洲网站| 亚洲午夜久久久精品电影院| 久久精品中文字幕免费| 亚洲国产精品VA在线看黑人 | 亚洲人成影院在线| 免费精品久久天干天干| 亚洲色偷偷综合亚洲AV伊人| 永久免费观看黄网站| 亚洲视频在线精品| 久久一区二区三区免费| 亚洲老妈激情一区二区三区| 很黄很污的网站免费| 久久亚洲精品中文字幕| 性xxxxx免费视频播放| 亚洲高清毛片一区二区| 四只虎免费永久观看| 一级做a免费视频观看网站| 亚洲精品你懂的在线观看| 无码人妻一区二区三区免费n鬼沢| 中文字幕亚洲综合精品一区| 一个人看的www在线观看免费| 亚洲色偷偷综合亚洲av78| 亚洲国产一成久久精品国产成人综合 | 久久这里只精品99re免费 | 亚洲18在线天美| 色吊丝永久在线观看最新免费| 国产精品亚洲lv粉色| 亚洲国产精品无码专区| 妻子5免费完整高清电视| 综合一区自拍亚洲综合图区| 亚洲人成网77777亚洲色 | 国产一卡二卡≡卡四卡免费乱码| 国产精品免费久久久久影院| 亚洲欧洲精品视频在线观看| 在线观看亚洲免费| 男人都懂www深夜免费网站| 亚洲最大中文字幕无码网站| 中文字幕亚洲日本岛国片| 久久WWW免费人成一看片| 搜日本一区二区三区免费高清视频|