亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

前文傳送門: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á)式

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

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

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

    MyBatis是一個(gè)支持普通SQL查詢,存儲(chǔ)過程和高級(jí)映射的優(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ì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • Java發(fā)送https請(qǐng)求并跳過ssl證書驗(yàn)證方法

    Java發(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-11
  • Java程序中方法的用法重載和遞歸

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

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

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

    windows自帶的游戲《掃雷》是陪伴了無(wú)數(shù)人的經(jīng)典游戲,本文將利用Java語(yǔ)言實(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,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值。需要的朋友可以收藏下,方便下次瀏覽觀看
    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ì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評(píng)論