Recycler是一個輕量級的對象緩存池,用來實現對象的復用。下面是使用Recycler的一個簡單實例:
import io.netty.util.Recycler;
public class RecycleTest {
private static final Recycler<User> RECYCLER = new Recycler<User>() {
//沒有對象的時候,新建一個對象, 會傳入一個handler,在Recycler池里,所有的對象都會轉成DefaultHandle對象
@Override
protected User newObject(Handle<User> handle) {
return new User(handle);
}
};
private static class User {
private final Recycler.Handle<User> handle;
public User(Recycler.Handle<User> handle) {
this.handle = handle;
}
public void recycle() {
//通過handler進行對象的回收
handle.recycle(this);
}
}
public static void main(String[] args) {
User user = RECYCLER.get();
//直接調用user方法進行對象的回收
user.recycle();
User user1 = RECYCLER.get();
//這里會返回true
System.out.println(user1 == user);
}
}
Recycler對象的創建
Recycler內部通過FastThreadLocal里的Stack棧來保存對象池,每次通過get方法從池中得到對象的時候,先通過FastThreadLocal得到Stack對象,具體的參數含義如下圖所示:Stack里通過數組存儲著回收的對象,構造方法如下圖:
Stack的構造方法
對象的回收
Recycler對象的回收會調用stack的push方法將對象放入到棧里,這樣就完成了對象的回收,具體邏輯如下:在push方法里,根據線程的不同,又可以分為同線程的回收,與異線程的回收。
同線程對象的回收
線程的回收相對比較簡單,將對象放到Stack棧里就完成了對象的回收,代碼如下:判斷對象是否回收的邏輯:
異線程對象的回收
異線程的回收是指創建對象的線程與調用recycler方法的線程不是同一個線程,這時候的回收邏輯就相對復雜了,里面用到了兩個對象,分別為:
- WeakOrderQueue 存儲其它線程回收到本線程的對象,當某個線程從Stack中獲取不到對象時會從WeakOrderQueue中獲取對象。每個線程的Stack擁有1個WeakOrderQueue鏈表,鏈表每個節點對應1個其它線程的WeakOrderQueue,其它線程回收到該Stack的對象就存儲在這個WeakOrderQueue里。
- Link: WeakOrderQueue中包含1個Link鏈表,回收對象存儲在鏈表某個Link節點里,當Link節點存儲的回收對象滿了時會新建1個Link放在Link鏈表尾,Link的容量為16。
對象結構如下圖所示:
具體的回收過程可以分為: -
獲取WeakOrderQueue
-
如果沒有相應的WeakOrderQueeu,則會創建WeakOrderQueue, 將創建線程的Stack與回收線程的WeakOrderQueue進行綁定,具體的代碼如下:
-
將對象追加到WeakOrderQueue
-
WeakOrderQueue的構造方法如下:
-
Link構造方法
獲取一個對象
可以通過get方法從recycler對象里獲取一個緩存的對象,下面是get方法的邏輯:Recycler的get方法邏輯
從其它線程獲取對象放到stack里
-
從其它線程獲取對象入口
-
從其它線程攻取對象
-
將Link集合里的對象移到stack里,邏輯如下圖: