欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Netty分布式高性能工具類recycler的使用及創(chuàng)建

 更新時(shí)間:2022年03月29日 16:15:58   作者:向南是個(gè)萬(wàn)人迷  
這篇文章主要為大家介紹了Netty分布式高性能工具類recycler的使用和創(chuàng)建,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步

前文傳送門:Netty分布式FastThreadLocal的set方法實(shí)現(xiàn)邏輯剖析

recycler的使用

這一小節(jié)開(kāi)始學(xué)習(xí)recycler相關(guān)的知識(shí), recycler是netty實(shí)現(xiàn)的一個(gè)輕量級(jí)對(duì)象回收站, 在netty中, recycler的使用也是相當(dāng)之頻繁的

recycler作用是保證了對(duì)象的循環(huán)利用, 對(duì)象使用完可以通過(guò)recycler回收, 需要再次使用則從對(duì)象池中取出, 不用每次都創(chuàng)建新對(duì)象從而減少對(duì)系統(tǒng)資源的占用, 同時(shí)也減輕了gc的壓力

這里看一個(gè)示例

public class RecyclerDemo {
    private static final Recycler<User> RECYCLER = new Recycler<User>() {
        @Override
        protected User newObject(Handle<User> handle) {
            return new User(handle);
        }
    };
    static class User{
        private final Recycler.Handle<User> handle;
        public User(Recycler.Handle<User> handle){
            this.handle=handle;
        }
        public void recycle(){
            handle.recycle(this);
        }
    }
    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的成員變量RECYCLER, 在匿名內(nèi)部類中重寫了newObject方法, 也就是創(chuàng)建對(duì)象的方法, 該方法就是用戶自定義的

這里newObject返回的new User(handle), 代表當(dāng)回收站沒(méi)有此類對(duì)象的時(shí)候, 可以通過(guò)這種方式創(chuàng)建對(duì)象

成員變量RECYCLER, 可以用來(lái)對(duì)此類對(duì)象的回收和再利用

定一個(gè)了一個(gè)靜態(tài)內(nèi)部類User, User中有個(gè)成員變量handle, 在構(gòu)造方法中為其賦值, handle的作用, 就是用于對(duì)象回收的

并且定義了一個(gè)方法recycle, 方法體中通過(guò)handle.recycle(this)這種方式將自身對(duì)象進(jìn)行回收, 通過(guò)這步操作, 就可以將對(duì)象回收到Recycler中

以上邏輯先做了解, 之后會(huì)進(jìn)行詳細(xì)分析

在main方法中, 通過(guò)RECYCLER的get方法獲取一個(gè)user, 然后進(jìn)行回收

再通過(guò)get方法將回收站的對(duì)象取出, 再次進(jìn)行回收, 最后判斷兩次取出的對(duì)象是否為一個(gè)對(duì)象, 最后結(jié)果輸出為true

以上demo就可以說(shuō)明Recycler的回收再利用的功能

簡(jiǎn)單介紹了demo, 我們就詳細(xì)的分析Recycler的機(jī)制

在Recycler的類的源碼中, 我們看到這一段邏輯

private final FastThreadLocal<Stack<T>> threadLocal = new FastThreadLocal<Stack<T>>() {
    @Override
    protected Stack<T> initialValue() {
        return new Stack<T>(Recycler.this, Thread.currentThread(), maxCapacityPerThread, maxSharedCapacityFactor, 
                ratioMask, maxDelayedQueuesPerThread);
    }
};

這一段邏輯我們并不陌生, 在上一小節(jié)的學(xué)習(xí)中我們知道, 這里用于保存線程共享對(duì)象, 而這里的共享對(duì)象, 就是一個(gè)Stack類型的對(duì)象

每個(gè)stack中維護(hù)著一個(gè)DefaultHandle類型的數(shù)組, 用于盛放回收的對(duì)象, 有關(guān)stack和線程的關(guān)系如圖所示:

8-3-1

也就是說(shuō)在每個(gè)Recycler中, 都維護(hù)著一個(gè)線程共享的棧, 用于對(duì)一類對(duì)象的回收

跟到Stack的構(gòu)造方法中

Stack(Recycler&lt;T&gt; parent, Thread thread, int maxCapacity, int maxSharedCapacityFactor, 
      int ratioMask, int maxDelayedQueues) {
    this.parent = parent;
    this.thread = thread;
    this.maxCapacity = maxCapacity;
    availableSharedCapacity = new AtomicInteger(max(maxCapacity / maxSharedCapacityFactor, LINK_CAPACITY));
    elements = new DefaultHandle[min(INITIAL_CAPACITY, maxCapacity)];
    this.ratioMask = ratioMask;
    this.maxDelayedQueues = maxDelayedQueues;
}

首先介紹幾個(gè)構(gòu)造方法中初始化的關(guān)鍵屬性:

屬性parent表示Reclycer對(duì)象自身

屬性thread表示當(dāng)前stack綁定的哪個(gè)線程

屬性maxCapacity表示當(dāng)前stack的最大容量, 表示stack最多能盛放多少個(gè)元素

屬性elements, 就表示stack中存儲(chǔ)的對(duì)象, 類型為DefaultHandle, 可以被外部對(duì)象引用, 從而實(shí)現(xiàn)回收

屬性ratioMask是用來(lái)控制對(duì)象回收的頻率的, 也就是說(shuō)每次通過(guò)Reclycer回收對(duì)象的時(shí)候, 不是每次都會(huì)進(jìn)行回收, 而是通過(guò)該參數(shù)控制回收頻率

屬性maxDelayedQueues, 這里稍微有些復(fù)雜, 在很多時(shí)候, 一個(gè)線程創(chuàng)建的對(duì)象, 有可能會(huì)被另一個(gè)線程所釋放, 而另一個(gè)線程釋放的對(duì)象是不會(huì)放在當(dāng)前線程的stack中的, 而是會(huì)存放在一個(gè)叫做WeakOrderQueue的數(shù)據(jù)結(jié)構(gòu)中, 里面也是存放著一個(gè)個(gè)DefaultHandle, WeakOrderQueue會(huì)存放線程1創(chuàng)建的并且在線程2進(jìn)行釋放的對(duì)象

這里只是稍作了解, 之后的會(huì)對(duì)此做詳細(xì)剖析, 這里我們只需知道, maxDelayedQueues屬性的意思就是我這個(gè)線程能回收幾個(gè)其他創(chuàng)建的對(duì)象的線程, 假設(shè)當(dāng)前線程是線程1, maxDelayedQueues為2, 那么我線程1回收了線程2創(chuàng)建的對(duì)象, 又回收了線程3創(chuàng)建的對(duì)象, 那么不可能回收線程4創(chuàng)建的對(duì)象了, 因?yàn)閙axDelayedQueues2, 我只能回收兩個(gè)線程創(chuàng)建的對(duì)象

屬性availableSharedCapacity, 表示在線程1中創(chuàng)建的對(duì)象, 在其他線程中緩存的最大個(gè)數(shù), 同樣, 相關(guān)邏輯會(huì)在之后的內(nèi)容進(jìn)行剖析

另外介紹兩個(gè)沒(méi)有在構(gòu)造方法初始化的屬性:

private WeakOrderQueue cursor, prev;
private volatile WeakOrderQueue head;

這里相當(dāng)于指針, 用于指向WeakOrderQueue的, 這里也是稍作了解, 之后會(huì)進(jìn)行詳細(xì)剖析

有關(guān)stack異線程之間對(duì)象的關(guān)系如圖所示(簡(jiǎn)略):

8-3-2

我們?cè)倮^續(xù)介紹Recycler的構(gòu)造方法, 同時(shí)熟悉有關(guān)stack各個(gè)參數(shù)的默認(rèn)值:

protected Recycler() {
    this(DEFAULT_MAX_CAPACITY_PER_THREAD);
}

這里調(diào)用了重載的構(gòu)造方法, 并傳入了參數(shù)DEFAULT_MAX_CAPACITY_PER_THREAD

DEFAULT_MAX_CAPACITY_PER_THREAD的默認(rèn)值是32768, 在static塊中被初始化的, 我們可以跟進(jìn)去自行分析

這個(gè)值就代表的每個(gè)線程中, stack中最多回收的元素的個(gè)數(shù)

繼續(xù)跟重載的構(gòu)造方法

protected Recycler(int maxCapacityPerThread) {
    this(maxCapacityPerThread, MAX_SHARED_CAPACITY_FACTOR);
}

這里又調(diào)用了重載的構(gòu)造方法, 并且傳入剛才傳入的32768和MAX_SHARED_CAPACITY_FACTOR

MAX_SHARED_CAPACITY_FACTOR默認(rèn)值是2, 同樣在static塊中進(jìn)行了初始化, 有關(guān)該屬性的用處稍后講解

繼續(xù)跟構(gòu)造方法:

protected Recycler(int maxCapacityPerThread, int maxSharedCapacityFactor) {
    this(maxCapacityPerThread, maxSharedCapacityFactor, RATIO, MAX_DELAYED_QUEUES_PER_THREAD);
}

這里同樣調(diào)用了重載的構(gòu)造方法, 傳入了剛才32768和2, 還有兩個(gè)屬性RATIO和MAX_DELAYED_QUEUES_PER_THREAD

RATIO也在static中被初始化, 默認(rèn)值是8

同上, MAX_DELAYED_QUEUES_PER_THREAD的默認(rèn)值是2倍cpu核數(shù)

我們繼續(xù)跟構(gòu)造方法:

protected Recycler(int maxCapacityPerThread, int maxSharedCapacityFactor, 
                   int ratio, int maxDelayedQueuesPerThread) {
    ratioMask = safeFindNextPositivePowerOfTwo(ratio) - 1;
    if (maxCapacityPerThread &lt;= 0) {
        this.maxCapacityPerThread = 0;
        this.maxSharedCapacityFactor = 1;
        this.maxDelayedQueuesPerThread = 0;
    } else {
        this.maxCapacityPerThread = maxCapacityPerThread;
        this.maxSharedCapacityFactor = max(1, maxSharedCapacityFactor);
        this.maxDelayedQueuesPerThread = max(0, maxDelayedQueuesPerThread);
    }
}

這里將幾個(gè)屬性進(jìn)行了初始化

首先看ratioMask, 這里的方法safeFindNextPositivePowerOfTwo的參數(shù)ratio為8, 該方法的意思就是大于等于8的2的冪次方-1, 這里就是ratioMask就是7

maxCapacityPerThread是剛才分析的32768, 是一個(gè)大于0的數(shù), 所以進(jìn)入else

maxCapacityPerThread為32768

maxSharedCapacityFactor的值為2

maxDelayedQueuesPerThread的值為2倍CPU核數(shù)

我們?cè)倩氐絊tack的構(gòu)造方法中

Stack(Recycler&lt;T&gt; parent, Thread thread, int maxCapacity, int maxSharedCapacityFactor, 
      int ratioMask, int maxDelayedQueues) {
    this.parent = parent;
    this.thread = thread;
    this.maxCapacity = maxCapacity;
    availableSharedCapacity = new AtomicInteger(max(maxCapacity / maxSharedCapacityFactor, LINK_CAPACITY));
    elements = new DefaultHandle[min(INITIAL_CAPACITY, maxCapacity)];
    this.ratioMask = ratioMask;
    this.maxDelayedQueues = maxDelayedQueues;
}

根據(jù)Recycler初始化屬性的邏輯, 我們可以知道Stack中幾個(gè)屬性的值:

maxCapacity默認(rèn)值為32768

ratioMask默認(rèn)值為7

maxDelayedQueues默認(rèn)值是兩倍cpu核數(shù)

availableSharedCapacity的默認(rèn)值是32768/2, 也就是16384

以上就是Recycler創(chuàng)建的相關(guān)邏輯,更多關(guān)于Netty分布式工具類recycler使用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論