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

Netty分布式從recycler對象回收站獲取對象過程剖析

 更新時間:2022年03月29日 16:29:24   作者:向南是個萬人迷  
這篇文章主要為大家介紹了Netty分布式從recycler獲取對象的過程源碼剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前文傳送門:Netty分布式高性能工具類recycler的使用及創(chuàng)建

從對象回收站中獲取對象

我們回顧上一小節(jié)demo的main方法中

從回收站獲取對象

public static void main(String[] args){
    User user1 = RECYCLER.get();
    user1.recycle();
    User user2 = RECYCLER.get();
    user2.recycle();
    System.out.println(user1==user2);
}

這個通過Recycler的get方法獲取對象, 我們跟到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最多能緩存多少個對象, 如果緩存0個, 說明對象將一個都不會回收

這個通過調(diào)用newObject創(chuàng)建一個對象, 并傳入一個NOOP_HANDLE, NOOP_HANDLE是一個handle, 我們看其定義:

private static final Handle NOOP_HANDLE = new Handle() {
    @Override
    public void recycle(Object object) {
        
    }
};

這里的recycle方法是一個空實(shí)現(xiàn), 代表不進(jìn)行任何對象回收

回到get方法中

我們看第二步 

Stack<T> stack = threadLocal.get(); 

這里通過FastThreadLocal對象拿到當(dāng)前線程的stack, 有關(guān)FastThreadLocal獲取對象的邏輯之前小節(jié)剖析過, 這里不再贅述

獲取stack之后, 從stack中pop出一個handle, 這個handle做用我們稍后分析

如果取出的對象為null, 說明當(dāng)前回收站內(nèi)沒有任何對象, 通常第一次執(zhí)行到這里對象還沒回收, 這里就會是null, 這樣則會通過stack.newHandle()創(chuàng)建一個handle

創(chuàng)建出來的handle的value屬性, 通過我們重寫的newObject方法進(jìn)行賦值, 也就是我們demo中的user

我們跟進(jìn)newHandle方法

DefaultHandle<T> newHandle() {
    return new DefaultHandle<T>(this);
}

這里創(chuàng)建一個DefaultHandle對象, 并傳入this, 這里的this是當(dāng)前stack

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

DefaultHandle(Stack<?> stack) {
    this.stack = stack;
}

這里初始化了stack屬性

DefaultHandle中還有個value的成員變量

private Object value;

這里的value就用來綁定回收的對象本身

回到get方法中:

分析handle, 我們回到上一步:

DefaultHandle<T> handle = stack.pop();

我們分析從stack中彈出一個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的對象數(shù)

如果size為0, 則調(diào)用scavenge方法, 這個方法是異線程回收對象的方法, 我們放在之后的小節(jié)進(jìn)行分析

size大于零, 則size進(jìn)行自減, 代表取出一個元素

然后通過size的數(shù)組下標(biāo)的方式將handle取出

之后將當(dāng)前下標(biāo)設(shè)置為null

最后將屬性recycleId, lastRecycledId, size進(jìn)行賦值

recycleId和lastRecycledId我們會在之后的小節(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;
}

無論是從stack中彈出的handle, 還是創(chuàng)建的handle, 最后都要通過handle.value拿到我們實(shí)際使用的對象

以上就是從對象回收站獲取對象的過程,更多關(guān)于Netty分布式recycler獲取對象的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 一篇文章帶你了解jdk1.8新特性--為什么使用lambda表達(dá)式

    一篇文章帶你了解jdk1.8新特性--為什么使用lambda表達(dá)式

    Lambda是一個匿名函數(shù),我們可以把Lambda表達(dá)式理解為是一段可以傳遞的代碼,本篇文章就帶你了解,希望能給你帶來幫助
    2021-08-08
  • JAVA MyBatis入門學(xué)習(xí)過程記錄

    JAVA MyBatis入門學(xué)習(xí)過程記錄

    MyBatis是一個支持普通SQL查詢,存儲過程和高級映射的優(yōu)秀持久層框架。這篇文章主要介紹了mybatis框架入門學(xué)習(xí)教程,需要的朋友可以參考下,希望能幫助到你
    2021-06-06
  • java調(diào)用ffmpeg實(shí)現(xiàn)視頻轉(zhuǎn)換的方法

    java調(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-06
  • knife4j?整合?springboot的過程詳解

    knife4j?整合?springboot的過程詳解

    這篇文章主要介紹了knife4j整合springboot的過程,本次整合springboot版本為2.3.12,本文通過圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-09-09
  • Java發(fā)送https請求并跳過ssl證書驗(yàn)證方法

    Java發(fā)送https請求并跳過ssl證書驗(yàn)證方法

    最近在負(fù)責(zé)一個對接第三方服務(wù)的事情,在對接期間因?yàn)榈谌椒?wù)為https的請求,這篇文章主要給大家介紹了關(guān)于Java發(fā)送https請求并跳過ssl證書驗(yàn)證的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • Java程序中方法的用法重載和遞歸

    Java程序中方法的用法重載和遞歸

    Java語言中的“方法”在其他語言當(dāng)中也可能被稱為“函數(shù)”(Function)。對于一些復(fù)雜的代碼邏輯,如果希望重復(fù)使用這些代碼,并且做到“隨時任意使用”,那么就可以將這些代碼放在一個大括號“{}”當(dāng)中,并且起一個名字。使用代碼的時候,直接找到名字調(diào)用即可
    2021-10-10
  • Java實(shí)現(xiàn)掃雷游戲的代碼分享

    Java實(shí)現(xiàn)掃雷游戲的代碼分享

    windows自帶的游戲《掃雷》是陪伴了無數(shù)人的經(jīng)典游戲,本文將利用Java語言實(shí)現(xiàn)這一經(jīng)典的游戲,文中的示例代碼講解詳細(xì),感興趣的可以學(xué)習(xí)一下
    2022-05-05
  • Socket與ServerSocket類構(gòu)造方法與API

    Socket與ServerSocket類構(gòu)造方法與API

    今天小編為大家整理了Socket與ServerSocket類構(gòu)造方法與API,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值。需要的朋友可以收藏下,方便下次瀏覽觀看
    2021-12-12
  • Java與Oracle實(shí)現(xiàn)事務(wù)(JDBC事務(wù))實(shí)例詳解

    Java與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)方法(圖文教程)

    這篇文章主要介紹了在eclipse中使用SVN的實(shí)現(xiàn)方法(圖文教程),文中通過圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評論