干掉Random:這個(gè)類才是獲取隨機(jī)數(shù)的王者!
前言
ThreadLocalRandom
UNSAFE.putLong(t = Thread.currentThread(), SEED, r = UNSAFE.getLong(t, SEED) + GAMMA);Thread t = Thread.currentThread();long r = UNSAFE.getLong(t, SEED) + GAMMA;UNSAFE.putLong(t, SEED, r);
功能
不過再仔細(xì)看 ThreadLocalRandom 類的核心代碼,發(fā)現(xiàn)并不是簡單的 Map 操作,它的 getLong() 方法需要傳入兩個(gè)參數(shù),而 putLong() 方法需要三個(gè)參數(shù),查看源碼發(fā)現(xiàn)它們都是 native 方法,我們看不到具體的實(shí)現(xiàn)。兩個(gè)方法簽名分別是:
public native long getLong(Object var1, long var2);public native void putLong(Object var1, long var2, long var4);
雖然看不到具體實(shí)現(xiàn),但我們可以查得到它們的功能,下面是兩個(gè)方法的功能
介紹:
putLong(object, offset, value) 可以將 object 對象內(nèi)存地址偏移 offset 后的位置后四個(gè)字節(jié)設(shè)置為 value。
getLong(object, offset) 會從 object 對象內(nèi)存地址偏移 offset 后的位置讀取四個(gè)字節(jié)作為 long 型返回。
那么這兩個(gè)方法”不安全”在哪呢?
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {// Unsafe 設(shè)置了構(gòu)造方法私有,getUnsafe 獲取實(shí)例方法包私有,在包外只能通過反射獲取Field field = Unsafe.class.getDeclaredField("theUnsafe");field.setAccessible(true);Unsafe unsafe = (Unsafe) field.get(null);// Test 類是一個(gè)隨手寫的測試類,只有一個(gè) String 類型的測試類Test test = new Test();test.ttt = "12345";unsafe.putLong(test, 12L, 2333L);System.out.println(test.value);}
不過 Unsafe 的其他方法可不一定像這一對方法一樣,使用他們時(shí)可能需要注意另外的安全問題,之后有遇到再說。
那么 ThreadLocalRandom 是不是安全的呢,再回過頭來看一下它的實(shí)現(xiàn)。
ThreadLocalRandom 的實(shí)現(xiàn)需要 Thread 對象的配合,在 Thread 對象內(nèi)存在著一個(gè)屬性 threadLocalRandomSeed,它保存著這個(gè)線程專屬的隨機(jī)種子,而這個(gè)屬性在 Thread 對象的 offset,是在 ThreadLocalRandom 類加載時(shí)就確定了的,具體方法是 SEED = UNSAFE.objectFieldOffset(Thread.class.getDeclaredField("threadLocalRandomSeed"));
我們知道一個(gè)對象所占用的內(nèi)存大小在類被加載后就確定了的,所以使用 Unsafe.objectFieldOffset(class, fieldName) 可以獲取到某個(gè)屬性在類中偏移量,而在找對了偏移量,又能確定數(shù)據(jù)類型時(shí),使用 ThreadLocalRandom 就是很安全的。
在查找這些問題的過程中,我也產(chǎn)生了兩個(gè)疑問點(diǎn)。
使用場景
內(nèi)存布局
在寫代碼時(shí)還是要多注意查看依賴庫的具體實(shí)現(xiàn),不然可能踩到意想不到的坑,而且多看看并沒有壞處,仔細(xì)研究一下還能學(xué)到更多。
感謝您的閱讀,也歡迎您發(fā)表關(guān)于這篇文章的任何建議,關(guān)注我,技術(shù)不迷茫!小編到你上高速。
正文結(jié)束
1.心態(tài)崩了!稅前2萬4,到手1萬4,年終獎扣稅方式1月1日起施行~
2.深圳一普通中學(xué)老師工資單曝光,秒殺程序員,網(wǎng)友:敢問是哪個(gè)學(xué)校畢業(yè)的?
3.從零開始搭建創(chuàng)業(yè)公司后臺技術(shù)棧
5.清華大學(xué):2021 元宇宙研究報(bào)告!

