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函式了,也就是說,乙個執行緒在例項化的時候,他能做什麼就已經定下來了,要做別的事,就要新開乙個執行緒.這感覺就和執行緒池的思想違背了,怎麼樣從執行緒池裡面拿乙個執行緒出來就可以執行呢?執行完了然後再放回去呢?第二個疑惑...