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

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

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

    聶永的博客

    記錄工作/學(xué)習(xí)的點(diǎn)點(diǎn)滴滴。

    Fork/Join模式(JSR166y)手記之ThreadLocalRandom

    ThreadLocalRandom是一個(gè)可以獨(dú)立使用的、用于生成隨機(jī)數(shù)的類。繼承自Random,但性能超過Random,所謂“青出于藍(lán)而勝于藍(lán)”。其API所提供方法,不多,父類Random具有的,它也一樣具有。從表明看,是一個(gè)單例模式,其實(shí)不然:
    private static final ThreadLocal localRandom =
    new ThreadLocal() {
    protected ThreadLocalRandom initialValue() {
    return new ThreadLocalRandom();
    }
    };

    ThreadLocalRandom() {
    super();
    initialized = true;
    }


    public static ThreadLocalRandom current() {
    return localRandom.get();
    }
    采用ThreadLocal進(jìn)行包裝的Random子類,每線程對應(yīng)一個(gè)ThreadLocalRandom實(shí)例。測試代碼:
    @Test
    public void testInstance() {
    final ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();
    final List randomList = new ArrayList();
    final Phaser barrier = new Phaser(1);

    new Thread() {
    @Override
    public void run() {
    randomList.add(ThreadLocalRandom.current());
    barrier.arrive();
    }
    }.start();

    barrier.awaitAdvance(barrier.getPhase());
    if (randomList.isEmpty()) {
    throw new NullPointerException();
    }

    Assert.assertTrue(threadLocalRandom != randomList.get(0));
    }
    這么一包裝,在性能上可以趕超Math.random(),不錯(cuò)。
    @Test
    public void testSpeed() {
    final int MAX = 100000;
    ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();

    long start = System.nanoTime();
    for (int i = 0; i < MAX; i++) {
    threadLocalRandom.nextDouble();
    }
    long end = System.nanoTime() - start;
    System.out.println("use time1 : " + end);

    long start2 = System.nanoTime();
    for (int i = 0; i < MAX; i++) {
    Math.random();
    }
    long end2 = System.nanoTime() - start2;
    System.out.println("use time2 : " + end2);

    Assert.assertTrue(end2 > end);
    }
    非規(guī)范的性能測試,某次輸出結(jié)果:
    use time1 : 3878481
    use time2 : 8633080
    性能差別不止兩倍啊,哈哈。
    再看Math.random(),其生成也是依賴于Random類:
    private static Random randomNumberGenerator;

    private static synchronized void initRNG() {
    if (randomNumberGenerator == null)
    randomNumberGenerator = new Random();
    }

    public static double random() {
    if (randomNumberGenerator == null) initRNG();
    return randomNumberGenerator.nextDouble();
    }
    很奇怪,性能為什么差那么遠(yuǎn)呢?可能個(gè)各自的next函數(shù)不同造成。看一下Random中的next(int bits)方法實(shí)現(xiàn):
    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));
    }
    而ThreadLocalRandom的重寫版本為:
    protected int next(int bits) {  
    rnd = (rnd * multiplier + addend) & mask;
    return (int) (rnd >>> (48-bits));
    }
    相比ThreadLocalRandom的next(int bits)函數(shù)實(shí)現(xiàn)上更為簡練,不存在seed的CAS操作,并且少了很多的運(yùn)算量。
    更為詳細(xì)的機(jī)制研讀,請閱讀參考資料中鏈接。
    另外,ThreadLocalRandom 也提供了易用的,兩個(gè)數(shù)字之間的隨機(jī)數(shù)生成方式。類似于:
    nextDouble(double least, double bound)
    nextInt(int least, int bound)
    nextLong(long least, long bound)
    隨機(jī)數(shù)的生成范圍為 最小值 <= 隨機(jī)數(shù) < 最大值。可以包含最小值,但不包含最大值。
    @Test
    public void testHowtoUse(){
    final ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();
    final int MAX = 100;
    int result = threadLocalRandom.nextInt(0, 100);
    Assert.assertTrue(MAX > result);
    }
    嗯,還有,不支持setSeed方法。
    曾經(jīng)JDK 7中,ThreadLocalRandom 存在隨機(jī)多個(gè)線程隨機(jī)數(shù)生成相同的bug,但最新版本中,已不存在,被修復(fù)了,可以放心使用。從現(xiàn)在開始,完全可以使用ThreadLocalRandom替代Random,尤其是在并發(fā)、并行、多任務(wù)等環(huán)境下,會比在多線程環(huán)境下使用公共共享的Random對象實(shí)例更為有效。
    代碼清單:

    參考資料:
    1. Java 7: How to write really fast Java code

    posted on 2012-02-04 11:29 nieyong 閱讀(1575) 評論(0)  編輯  收藏 所屬分類: Java

    公告

    所有文章皆為原創(chuàng),若轉(zhuǎn)載請標(biāo)明出處,謝謝~

    新浪微博,歡迎關(guān)注:

    導(dǎo)航

    <2012年2月>
    2930311234
    567891011
    12131415161718
    19202122232425
    26272829123
    45678910

    統(tǒng)計(jì)

    常用鏈接

    留言簿(58)

    隨筆分類(130)

    隨筆檔案(151)

    個(gè)人收藏

    最新隨筆

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 麻豆高清免费国产一区| 最近中文字幕无免费| 国产免费人成视频在线观看| 国产成+人+综合+亚洲专| 最近中文字幕大全中文字幕免费| 亚洲日产韩国一二三四区| aaa毛片免费观看| 在线精品亚洲一区二区小说| 亚洲阿v天堂在线2017免费| 亚洲一区二区三区无码影院| yellow视频免费在线观看| 国产亚洲成归v人片在线观看| 一区二区三区免费视频观看| 久久久久亚洲AV无码专区桃色| 国产精品视频全国免费观看| 伊人久久大香线蕉亚洲五月天| 丝袜足液精子免费视频| 亚洲va无码手机在线电影| 99在线视频免费| 亚洲一区二区三区国产精品无码| 成年在线观看网站免费| 性色av极品无码专区亚洲| 亚洲日韩在线中文字幕第一页| 成在人线av无码免费高潮喷水| 精品亚洲成AV人在线观看| 毛片免费视频播放| 国产成人不卡亚洲精品91| 中文字幕不卡亚洲| 99久久人妻精品免费一区| 亚洲中文字幕乱码AV波多JI | 无码精品人妻一区二区三区免费| 国产成人精品久久亚洲| a毛片在线免费观看| 亚洲欧洲春色校园另类小说| 免费观看a级毛片| 中文在线免费观看| 久久久久se色偷偷亚洲精品av | 中国在线观看免费高清完整版| 亚洲国产成人AV网站| 亚洲欧洲日产国码无码网站| 中文字幕在线免费|