執行緒探針的理解

2021-10-21 19:20:21 字數 2618 閱讀 1137

concurrenthashmap 在累加鍵值對個數的 addcount 函式中,使用 threadlocalrandom.getprobe() 得到執行緒的探針雜湊值。

在這裡,這個探針雜湊值的作用是雜湊執行緒,將執行緒和陣列中的不用元素對應起來,盡量避免執行緒爭用同一陣列元素。探針雜湊值和 map 裡使用的雜湊值的區別是,當執行緒發生陣列元素爭用後,可以改變執行緒的探針雜湊值,讓執行緒去使用另乙個陣列元素,而 map 中 key 物件的雜湊值,由於有定位 value 的需求,所以它是一定不能變的。

那麼這個探針雜湊值是在哪計算的呢?帶著這個問題我們繼續往下看。

threadlocalrandom.getprobe() 方法如下:

/**

* returns the probe value for the current thread without forcing

* initialization. note that invoking threadlocalrandom.current()

* can be used to force initialization on zero return.

*/static final int getprobe()

probe 是什麼?

// unsafe mechanics

private static final sun.misc.unsafe unsafe;

...private static final long probe;

...static catch (exception e)

}

可以看到 probe 表示的是 thread 類 threadlocalrandomprobe 欄位的偏移量。

所以 getprobe 方法的功能就是簡單的返回當前執行緒 threadlocalrandomprobe 欄位的值。

接著去 thread 類看看這個 threadlocalrandomprobe 字段,

/** probe hash value; nonzero if threadlocalrandomseed initialized */

@sun.misc.contended("tlr")

int threadlocalrandomprobe;

thread 類僅僅是定義了這個字段,並沒有將其初始化,其初始化工作由 threadlocalrandom 類來做。

threadlocalrandom 類的 localinit 方法完成初始化工作,

/**

* initialize thread fields for the current thread. called only

* when thread.threadlocalrandomprobe is zero, indicating that a

* thread local seed value needs to be generated. note that even

* though the initialization is purely thread-local, we need to

* rely on (static) atomic generators to initialize the values.

*/static final void localinit()

seed 和 probe 類似,它表示的是 thread 類 threadlocalrandomseed 欄位的偏移量。

在 threadlocalrandom 類的這個 localinit 方法裡,同時初始化了當前執行緒的 threadlocalrandomseed 欄位和 threadlocalrandomprobe 字段。

所以在 thread 類 threadlocalrandomprobe 欄位上的注釋中說:nonzero if threadlocalrandomseed initialized。就是說如果 threadlocalrandomseed 欄位被初始化了,threadlocalrandomprobe 欄位就非零。因為它倆是同時被初始化的。

除此之外,也可以通過 threadlocalrandom 類的 advanceprobe 方法更改當前執行緒 threadlocalrandomprobe 的值。

/**

* pseudo-randomly advances and records the given probe value for the

* given thread.

*/static final int advanceprobe(int probe)

concurrenthashmap 裡的 fulladdcount 方法會呼叫 threadlocalrandom.localinit() 初始化當前執行緒的探針雜湊值;當發生執行緒爭用後,也會呼叫 threadlocalrandom.advanceprobe(h) 更改當前執行緒的探針雜湊值,

private final void fulladdcount(long x, boolean wasuncontended) 

...h = threadlocalrandom.advanceprobe(h);

...}

光探針的細節

使用光照貼圖可以大幅度提公升場景渲染的真實程度,但缺點是光照貼圖無法作用在動態的物體上,所以看上去運動的物體和場景就顯得很不協調。因此,為了解決這個問題unity3d引入了光探針 probe lighting 技術模擬使用光照貼圖的效果。光探針照明的大致原理是 在某一光探針 light probe ...

執行緒的舉例理解

threadmessage starting messageloop thread 提示main執行緒起動 long starttime system.currenttimemillis 獲得當時時間點,用來判斷子執行緒啟動的時間 thread t new thread new messageloo...

執行緒池的理解

原來一直對執行緒池心存疑惑.第乙個疑惑是.執行緒類在例項化的時候就已經指定了run函式了,也就是說,乙個執行緒在例項化的時候,他能做什麼就已經定下來了,要做別的事,就要新開乙個執行緒.這感覺就和執行緒池的思想違背了,怎麼樣從執行緒池裡面拿乙個執行緒出來就可以執行呢?執行完了然後再放回去呢?第二個疑惑...