巩鹏军的博客

HOME

Netty内存池无锁设计

08 Jul 2022

本文是博客文章《详解 Recycler 对象池的精妙设计与实现》的摘要,只关注Netty无锁化设计部分。


1、常规锁同步设计

extent and xdes entry

锁同步发生场景:

2、Netty无锁化设计

2.1、数据结构

数据结构是代码分析的起点。

每个Thread一个Stack对象,每个Thread获取对象和释放对象都操作本thread对应的Stack:

extent and xdes entry

每个Thread的Stack持有一个WeakOrderQueue组成的链表,链表中的每个WeakOrderQueue节点仅供一个Thread使用,如上图所示:第一个WeakOrderQueue节点仅供Thread2使用,第二个WeakOrderQueue节点仅供Thread3使用,第三个WeakOrderQueue节点仅供Thread4使用,以此类推。这样Thread2、Thread3、Thread4之间就不会相互竞争了。

一个WeakOrderQueue内部的结构如下:(注:下图的head和上图的head无关)

extent and xdes entry

有了数据结构的布局图,分析起来就得心应手了。

3、无锁设计要点分析

我们以Thread1获取对象obj1交给Thread2使用,然后Thread2用完objc后将其释放的过程来分析无锁化是怎么达成的。

3.1、Thread1获取池化对象obj1

Thread1从对象池获取一个obj1,对象池返回的对象是obj1的包装对象Handle。Handle中会记录创建线程thread1的信息。

3.2、Thread1将池化对象obj1交给Thread2

常规的线程间交互,无特殊处理。

3.3、Thread2归还池化对象obj1 - pushLater

Thread2用户对象obj1后,准备归还。

3.4、Thread1释放池化对象obj1 - scavenge→transfer

Thread1遍历自己Stack中的WeakOrderQueue链表,转移每个WeakOrderQueue节点中的一个Link节点中的elements。

总结:经过精心的安排,将可能的资源竞争消除掉

4、参考资料

关于我

专注于IM即时通讯全技术栈的程序员,关注获取更多IM技术文章。

gongpengjunblog

IM小蓝天

微信扫描二维码,关注我的公众号