日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
ThreadLocalRandom類(lèi)原理分析

本文轉(zhuǎn)載自微信公眾號(hào)「一個(gè)程序員的成長(zhǎng)」,作者一個(gè)程序員的成長(zhǎng)。轉(zhuǎn)載本文請(qǐng)聯(lián)系一個(gè)程序員的成長(zhǎng)公眾號(hào)。

創(chuàng)新互聯(lián)建站于2013年創(chuàng)立,是專(zhuān)業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目成都做網(wǎng)站、成都網(wǎng)站建設(shè)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元漢中做網(wǎng)站,已為上家服務(wù),為漢中各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:028-86922220

1、Random類(lèi)及其局限性

 
 
 
  1. public int nextInt(int bound) {
  2.     if (bound <= 0)
  3.         throw new IllegalArgumentException(BadBound);
  4.     // 計(jì)算新的種子
  5.     int r = next(31);
  6.     int m = bound - 1;
  7.     // 根據(jù)新的種子計(jì)算隨機(jī)數(shù)
  8.     if ((bound & m) == 0)  // i.e., bound is a power of 2
  9.         r = (int)((bound * (long)r) >> 31);
  10.     else {
  11.         for (int u = r;
  12.              u - (r = u % bound) + m < 0;
  13.              u = next(31))
  14.             ;
  15.     }
  16.     return r;
  17. }
 
 
 
  1. protected int next(int bits) {
  2.     long oldseed, nextseed;
  3.     // 這是一個(gè)原子性的變量
  4.     AtomicLong seed = this.seed;
  5.     do {
  6.         // (1)、獲取老的種子
  7.         oldseed = seed.get();
  8.         // (2)、計(jì)算出新的種子
  9.         nextseed = (oldseed * multiplier + addend) & mask;
  10.     // (3)、CAS操作更新老的種子
  11.     } while (!seed.compareAndSet(oldseed, nextseed));
  12.     return (int)(nextseed >>> (48 - bits));
  13. }

Random小結(jié):

  • 面試:多線程下Random存在什么樣的問(wèn)題?

每個(gè)Random實(shí)例里面都有一個(gè)原子性的種子變量用來(lái)記錄當(dāng)前的種子值,當(dāng)要生成新的隨機(jī)數(shù)時(shí)需要根據(jù)當(dāng)前的種子計(jì)算新的種子并更新種子變量。當(dāng)在多線程環(huán)境下,多個(gè)線程會(huì)競(jìng)爭(zhēng)同一個(gè)原子變量的更新操作,由于原子變量的更新時(shí)CAS操作,同時(shí)只有一個(gè)線程會(huì)成功,所以會(huì)造成大量線程進(jìn)行自旋重試,從而降低并發(fā)性能。

可能出現(xiàn)的癥狀:如果并發(fā)請(qǐng)求非常多,自旋鎖一直重試,那么CPU會(huì)一直飆升。

2、ThreadLocalRandom

 
 
 
  1. public static ThreadLocalRandom current() {
  2.     if (UNSAFE.getInt(Thread.currentThread(), PROBE) == 0)
  3.         localInit();
  4.     return instance;
  5. }
 
 
 
  1. static final void localInit() {
  2.     int p = probeGenerator.addAndGet(PROBE_INCREMENT);
  3.     int probe = (p == 0) ? 1 : p; // skip 0
  4.     long seed = mix64(seeder.getAndAdd(SEEDER_INCREMENT));
  5.     Thread t = Thread.currentThread();
  6.     UNSAFE.putLong(t, SEED, seed);
  7.     UNSAFE.putInt(t, PROBE, probe);
  8. }

這個(gè)方法用來(lái)創(chuàng)建ThreadLocalRandom隨機(jī)數(shù)生成器,如果當(dāng)前線程中threadLocalRandomProbe的變量值為0,則說(shuō)明是第一次調(diào)用current方法,那么就調(diào)用localInit方法初始化種子變量。

這里使用了延遲初始化,在localInit方法中,并沒(méi)有初始化種子變量,而是在需要生成隨機(jī)數(shù)的時(shí)候再生成種子變量,這是一種優(yōu)化。

 
 
 
  1. static final void localInit() {
  2.     int p = probeGenerator.addAndGet(PROBE_INCREMENT);
  3.     int probe = (p == 0) ? 1 : p; // skip 0
  4.     long seed = mix64(seeder.getAndAdd(SEEDER_INCREMENT));
  5.     Thread t = Thread.currentThread();
  6.     UNSAFE.putLong(t, SEED, seed);
  7.     UNSAFE.putInt(t, PROBE, probe);
  8. }
 
 
 
  1. final long nextSeed() {
  2.     Thread t; long r; // read and update per-thread seed
  3.     // 生成新種子(獲取當(dāng)前線程種子 + 種子增量)
  4.     UNSAFE.putLong(t = Thread.currentThread(), SEED,
  5.                    r = UNSAFE.getLong(t, SEED) + GAMMA);
  6.     return r;
  7. }

mix32是一個(gè)固定的算法,這里重點(diǎn)看下nextSeed方法,當(dāng)?shù)谝淮握{(diào)用的時(shí)候進(jìn)行初始化,獲取當(dāng)前線程threadLocalRandomSeed的值(第一次默認(rèn)值為0) + 種子增量,如果不是第一次那么獲取舊種子的值 + 種子增量生成新的種子變量并設(shè)置回去。這樣的話多線程環(huán)境下就避免了競(jìng)爭(zhēng),因?yàn)閠hreadLocalRandomSeed是Thread的一個(gè)變量,屬于線程級(jí)別。


文章名稱(chēng):ThreadLocalRandom類(lèi)原理分析
文章起源:http://m.5511xx.com/article/dpohecc.html