最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

recycler的使用

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

recycler作用是保證了對(duì)象的循環(huán)利用, 對(duì)象使用完可以通過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)回收站沒有此類對(duì)象的時(shí)候, 可以通過這種方式創(chuàng)建對(duì)象

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

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

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

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

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

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

以上demo就可以說明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

也就是說在每個(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是用來控制對(duì)象回收的頻率的, 也就是說每次通過Reclycer回收對(duì)象的時(shí)候, 不是每次都會(huì)進(jìn)行回收, 而是通過該參數(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è)沒有在構(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)文章!

  • Java多線程中的wait與notify方法詳解

    Java多線程中的wait與notify方法詳解

    這篇文章主要介紹了Java多線程中的wait與notify方法詳解,線程的調(diào)度是無序的,但有些情況要求線程的執(zhí)行是有序的,因此,我們可以使用 wait() 方法來使線程執(zhí)行有序,需要的朋友可以參考下
    2023-08-08
  • Springmvc請(qǐng)求參數(shù)類型轉(zhuǎn)換器及原生api代碼實(shí)例

    Springmvc請(qǐng)求參數(shù)類型轉(zhuǎn)換器及原生api代碼實(shí)例

    這篇文章主要介紹了Springmvc請(qǐng)求參數(shù)類型轉(zhuǎn)換器及原生api代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Java使用Graphics2D繪制SVG和PNG的方法

    Java使用Graphics2D繪制SVG和PNG的方法

    Java提供了許多圖形處理類和方法,如Graphics2D、AffineTransform、Stroke等,這些都可以用于繪制SVG圖像,Graphics2D是Java中用于繪制2D圖形的類,本文給大家介紹如何使用Graphics2D繪制SVG和PNG,需要的朋友可以參考下
    2023-06-06
  • 關(guān)于mybatis-plus邏輯刪除無效的問題

    關(guān)于mybatis-plus邏輯刪除無效的問題

    這篇文章主要介紹了mybatis-plus邏輯刪除無效,文中給大家提到了配置過程及全部代碼,代碼簡(jiǎn)單易懂,需要的朋友可以參考下
    2021-09-09
  • 詳解springboot熱啟動(dòng)與熱部署

    詳解springboot熱啟動(dòng)與熱部署

    本篇文章主要介紹了詳解springboot熱啟動(dòng)與熱部署,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • springboot實(shí)現(xiàn)定時(shí)器(一看即會(huì),非常簡(jiǎn)單)

    springboot實(shí)現(xiàn)定時(shí)器(一看即會(huì),非常簡(jiǎn)單)

    這篇文章主要介紹了springboot實(shí)現(xiàn)定時(shí)器(一看即會(huì),非常簡(jiǎn)單),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • SpringBoot實(shí)現(xiàn)定時(shí)發(fā)送郵件的三種方法案例詳解

    SpringBoot實(shí)現(xiàn)定時(shí)發(fā)送郵件的三種方法案例詳解

    這篇文章主要介紹了SpringBoot三種方法實(shí)現(xiàn)定時(shí)發(fā)送郵件的案例,Spring框架的定時(shí)任務(wù)調(diào)度功能支持配置和注解兩種方式Spring?Boot在Spring框架的基礎(chǔ)上實(shí)現(xiàn)了繼承,并對(duì)其中基于注解方式的定時(shí)任務(wù)實(shí)現(xiàn)了非常好的支持,本文給大家詳細(xì)講解,需要的朋友可以參考下
    2023-03-03
  • 細(xì)數(shù)java for循環(huán)中的那些坑

    細(xì)數(shù)java for循環(huán)中的那些坑

    這篇文章主要介紹了Java for循環(huán)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07
  • Java實(shí)現(xiàn)對(duì)中文字符串的排序功能實(shí)例代碼

    Java實(shí)現(xiàn)對(duì)中文字符串的排序功能實(shí)例代碼

    這篇文章主要介紹了Java實(shí)現(xiàn)中文字符串的排序功能實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2016-04-04
  • 最新評(píng)論

    聂荣县| 额敏县| 阿克| 安龙县| 华容县| 昆山市| 彭水| 无为县| 社会| 泰安市| 白城市| 南宁市| 绥芬河市| 靖远县| 望城县| 庆云县| 大同县| 上蔡县| 屯留县| 滨海县| 平度市| 文昌市| 美姑县| 镇康县| 崇信县| 华亭县| 吉木乃县| 涞源县| 疏附县| 英山县| 喀什市| 合江县| 北流市| 军事| 贵阳市| 福海县| 保定市| 白河县| 遂宁市| 边坝县| 廉江市|