Netty分布式從recycler對(duì)象回收站獲取對(duì)象過程剖析
前文傳送門:Netty分布式高性能工具類recycler的使用及創(chuàng)建
從對(duì)象回收站中獲取對(duì)象
我們回顧上一小節(jié)demo的main方法中
從回收站獲取對(duì)象
public static void main(String[] args){ User user1 = RECYCLER.get(); user1.recycle(); User user2 = RECYCLER.get(); user2.recycle(); System.out.println(user1==user2); }
這個(gè)通過Recycler的get方法獲取對(duì)象, 我們跟到get方法中:
public final T get() { if (maxCapacityPerThread == 0) { return newObject((Handle<T>) NOOP_HANDLE); } Stack<T> stack = threadLocal.get(); DefaultHandle<T> handle = stack.pop(); if (handle == null) { handle = stack.newHandle(); handle.value = newObject(handle); } return (T) handle.value; }
首先判斷maxCapacityPerThread是否為0, maxCapacityPerThread代表stack最多能緩存多少個(gè)對(duì)象, 如果緩存0個(gè), 說明對(duì)象將一個(gè)都不會(huì)回收
這個(gè)通過調(diào)用newObject創(chuàng)建一個(gè)對(duì)象, 并傳入一個(gè)NOOP_HANDLE, NOOP_HANDLE是一個(gè)handle, 我們看其定義:
private static final Handle NOOP_HANDLE = new Handle() { @Override public void recycle(Object object) { } };
這里的recycle方法是一個(gè)空實(shí)現(xiàn), 代表不進(jìn)行任何對(duì)象回收
回到get方法中
我們看第二步
Stack<T> stack = threadLocal.get();
這里通過FastThreadLocal對(duì)象拿到當(dāng)前線程的stack, 有關(guān)FastThreadLocal獲取對(duì)象的邏輯之前小節(jié)剖析過, 這里不再贅述
獲取stack之后, 從stack中pop出一個(gè)handle, 這個(gè)handle做用我們稍后分析
如果取出的對(duì)象為null, 說明當(dāng)前回收站內(nèi)沒有任何對(duì)象, 通常第一次執(zhí)行到這里對(duì)象還沒回收, 這里就會(huì)是null, 這樣則會(huì)通過stack.newHandle()創(chuàng)建一個(gè)handle
創(chuàng)建出來(lái)的handle的value屬性, 通過我們重寫的newObject方法進(jìn)行賦值, 也就是我們demo中的user
我們跟進(jìn)newHandle方法
DefaultHandle<T> newHandle() { return new DefaultHandle<T>(this); }
這里創(chuàng)建一個(gè)DefaultHandle對(duì)象, 并傳入this, 這里的this是當(dāng)前stack
跟到DefaultHandle的構(gòu)造方法中:
DefaultHandle(Stack<?> stack) { this.stack = stack; }
這里初始化了stack屬性
DefaultHandle中還有個(gè)value的成員變量
private Object value;
這里的value就用來(lái)綁定回收的對(duì)象本身
回到get方法中:
分析handle, 我們回到上一步:
DefaultHandle<T> handle = stack.pop();
我們分析從stack中彈出一個(gè)handle的邏輯
跟到pop方法中
DefaultHandle<T> pop() { int size = this.size; if (size == 0) { if (!scavenge()) { return null; } size = this.size; } size --; DefaultHandle ret = elements[size]; elements[size] = null; if (ret.lastRecycledId != ret.recycleId) { throw new IllegalStateException("recycled multiple times"); } ret.recycleId = 0; ret.lastRecycledId = 0; this.size = size; return ret; }
首先拿到size, size表示當(dāng)前stack的對(duì)象數(shù)
如果size為0, 則調(diào)用scavenge方法, 這個(gè)方法是異線程回收對(duì)象的方法, 我們放在之后的小節(jié)進(jìn)行分析
size大于零, 則size進(jìn)行自減, 代表取出一個(gè)元素
然后通過size的數(shù)組下標(biāo)的方式將handle取出
之后將當(dāng)前下標(biāo)設(shè)置為null
最后將屬性recycleId, lastRecycledId, size進(jìn)行賦值
recycleId和lastRecycledId我們會(huì)在之后的小節(jié)進(jìn)行分析
回到get方法中:
public final T get() { if (maxCapacityPerThread == 0) { return newObject((Handle<T>) NOOP_HANDLE); } Stack<T> stack = threadLocal.get(); DefaultHandle<T> handle = stack.pop(); if (handle == null) { handle = stack.newHandle(); handle.value = newObject(handle); } return (T) handle.value; }
無(wú)論是從stack中彈出的handle, 還是創(chuàng)建的handle, 最后都要通過handle.value拿到我們實(shí)際使用的對(duì)象
以上就是從對(duì)象回收站獲取對(duì)象的過程,更多關(guān)于Netty分布式recycler獲取對(duì)象的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
一篇文章帶你了解jdk1.8新特性--為什么使用lambda表達(dá)式
Lambda是一個(gè)匿名函數(shù),我們可以把Lambda表達(dá)式理解為是一段可以傳遞的代碼,本篇文章就帶你了解,希望能給你帶來(lái)幫助2021-08-08java調(diào)用ffmpeg實(shí)現(xiàn)視頻轉(zhuǎn)換的方法
這篇文章主要介紹了java調(diào)用ffmpeg實(shí)現(xiàn)視頻轉(zhuǎn)換的方法,較為詳細(xì)分析了java視頻格式轉(zhuǎn)換所需要的步驟及具體實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-06-06Java發(fā)送https請(qǐng)求并跳過ssl證書驗(yàn)證方法
最近在負(fù)責(zé)一個(gè)對(duì)接第三方服務(wù)的事情,在對(duì)接期間因?yàn)榈谌椒?wù)為https的請(qǐng)求,這篇文章主要給大家介紹了關(guān)于Java發(fā)送https請(qǐng)求并跳過ssl證書驗(yàn)證的相關(guān)資料,需要的朋友可以參考下2023-11-11Socket與ServerSocket類構(gòu)造方法與API
今天小編為大家整理了Socket與ServerSocket類構(gòu)造方法與API,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值。需要的朋友可以收藏下,方便下次瀏覽觀看2021-12-12Java與Oracle實(shí)現(xiàn)事務(wù)(JDBC事務(wù))實(shí)例詳解
這篇文章主要介紹了Java與Oracle實(shí)現(xiàn)事務(wù)(JDBC事務(wù))實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05在eclipse中使用SVN的實(shí)現(xiàn)方法(圖文教程)
這篇文章主要介紹了在eclipse中使用SVN的實(shí)現(xiàn)方法(圖文教程),文中通過圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07