netty-Buffer轻量级对象池实现分析

     netty是使用threadlocal变量来实现轻量级的对象池的,每个线程都拥有自己的对象池。netty自己实现了threadlocal语义,通过继承Thread类得到线程子类FastThreadLocalThread,FastThreadLocalThread持有一个成员变量InternalThreadLocalMap,每个线程将自己的对象池保存在这个变量对应的对象中。

UnpaddedInternalThreadLocalMap:是InternalThreadLocalMap的父类,其由许多属性构成,用于threadLocal的属性为一个Object数组indexedVariables,数组的每一位即对应一个threadLocal变量,threadLcoal变量可以操作这个位置(存取数据,数据类型由声明threadLocal变量时声明的泛型类型确定),而threadLocal对应位置的确定由UnpaddedInternalThreadLocalMap中的静态常量nextIndex确定,其是一个AtomicInteger类型,在threadLocal声明时,会获取nextIndex的最新值,同时nextIndex++。同时UnpaddedInternalThreadLocalMap还有一个类型为ThreadLocal<InternalThreadLocalMap>的静态变量slowThreadLocalMap,如果当前线程不是FastThreadLocalThread时,即没有成员变量InternalThreadLocalMap,因此通过该原生ThreadLocal变量来实现对象池,即将一个InternalThreadLocalMap对象保存在Thread的localMap中。(注意,ThreadLocal类型的变量是对应所有线程的,每个ThreadLocal变量的声明都会导致所有线程的Object数组位置被占用一个)。

InternalThreadLocalMap:提供一些静态方法用于对当前线程的InternalThreadLocalMap对象的Access。包括生成(只有真正使用时,才会为当前线程的InternalThreadLocalMap变量生成实际的对象),删除,存取。

FastThreadLocalThread:继承Thread。

FastThreadLocal:netty自己实现的ThreadLocal,用于对InternalThreadLocalMap类型中的成员变量Object数组indexedVariables进行操作。每个FastThreadLocal有一个成员变量index,在对象创建时会通过InternalThreadLocalMap的静态方法nextVariableIndex()对其进行赋值,实际是取InternalThreadLocalMap得静态成员变量nextIndex的最新值。index即代表其对Object数组indexedVariables的位置,表示该FastThreadLocal对象拥有该位置的控制权。

通过FastThreadLocalThread、InternalThreadLocalMap、FastThreadLocal这三个类,Netty就实现了一个底层是数组实现的ThreadLocal语义,相比于原生的通过Map实现的ThreadLocal其访问会变快。

Recycler:是一个根据netty自己实现的ThreadLocal语义实现的对象池。其有三个静态内部类Handle<T>、Stack<T>、WeakOrderQueue。2个FastThreadLocal属性(其中一个是静态的)。

             Handle<T>:是对象池的存储基本单位,每个handle对象持有实际存储的类型为T的对象

                Stack<T>:一个具有stack性质的对象池存储数据结构,也是实际保存在ThreadLoval对应的数组位置的对象结构。

      WeakOrderQueue:一个对象储备队列

FastThreadLocal<Stack>类型属性threadLocal:在InternalThreadLocalMap中存储一个Stack类型对象池。每个Recycler类的实例都会产生一个threadLocal对象,因此每个Recycler对象就是一个相应类型的对象池的实现,对于同一类型,一般是单例或者定义成静态变量。

static的FastThreadLocal<Map,WeakOrderQueue>>类型属性DELAYED_RECYCLED:同样是一个对象池,因为当一个handle需要回收时,这个handler不一定就在产生其的FastThreadLocalThread IO线程中,比如在自定义的业务线程池中执行完任务后需要回收对象,这样该handle就无法放回到IO线程对应的stack对象池中,因此需要定义一个static的对象池WeakOrderQueue,允许业务线程将需要回收的handle放入到对应的WeakOrderQueue中,这样当io线程需要获取新的handle时也就可以从对应的对象储备队列中获取。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 什么是对象池技术?对象池应用在哪些地方? 对象池其实就是缓存一些对象从而避免大量创建同一个类型的对象,类似线程池的...
    BlackManba_24阅读 9,773评论 0 8
  • Java SE 基础: 封装、继承、多态 封装: 概念:就是把对象的属性和操作(或服务)结合为一个独立的整体,并尽...
    Jayden_Cao阅读 6,411评论 0 8
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,463评论 19 139
  • 度过了一年的独行侠生活,大二返校的第三天。在看完综艺后回头一看发现室友们原来都出门了,有点丧啦…开始怀疑如果每天都...
    和我玩耍啊呵阅读 1,196评论 0 0
  • 我和妹妹的年龄差有点大,以前我都是在上学或是在外地,很少陪她们。其实和她们在一起,让我觉得我仿佛还是那个在田野间奔...
    伊人斓珊阅读 3,047评论 3 5