Netty的那些“锁”事儿
·分析同步问题的核心三要素
原子性:“并无一气呵成,岂能无懈可击”
可见性:“你做的改变,别人看不见”
有序性:“不按套路出牌”
·锁的分类
对竞争的态度:乐观锁(java.util.concurrent包中的原子类)与悲观锁(Synchronized)
等待锁的人是否公平而言:公平锁new ReentrantLock (true)与非公平锁new ReentrantLock ()
是否可以共享:共享锁与独享锁:ReadWriteLock,其读锁是共享锁,其写锁是独享锁
.Netty玩转锁的五个关键点:
·在意锁的对象和范围->减少粒度
新版本的这块儿代码已经被重构了,换了别的实现方式。
但这个例子本身就你能说明问题
·注意锁的对象本身大小->减少空间占用
Atomic long vs long:
前者是一个对象,包含对象头(object header)以用来保存 hashcode、lock等信息,32位系统占用8字节;64位系统占16字节,所以在64位系统情况下:
- volatile long = 8 bytes
- AtomicLong = 8 bytes (volatile long) + 16bytes(对象头)+8 bytes(引用)= 32 bytes
至少节约24字节!
结论:Atomic* objects -> Volatile primary type + Static Atomic*FieldUpdater
·注意锁的速度->提高并发性
例1∶记录内存分配字节数等功能用到的LongCounter
( io.netty.util.internal.PlatformDependent#newLongCounter() )
高并发时: java.util.concurrent.atomic.AtomicLong ->java.util.concurrent.atomic.LongAdder (JDK11)
结论:及时衡量、使用JDK最新的功能
不同场景选择不同的并发类-→>因需而变
例1:关闭和等待关闭事件执行器(Event Executor) :
object.wait/notify -> CountDownLatch
io.netty.util.concurrent.SingleThreadEventExecutor#threadLock:
例2: Nio Event loop中负责存储task的Queue
Jdk's LinkedBlockingQueue (MPMC) -> jctools' MPSC
io.netty.util.internal.PlatformDependent.Mpsc#newMpscQueue(int):
针对多生产者单消费者——自己实现了一个锁
MPMC——multi producermulti multi consumer
MPSC—— multi producermulti sigle consumer
衡量好锁的价值->能不用则不用
局部串行:Channel的I/O请求处理Pipeline是串行的
整体并行:多个串行化的线程(NioEventLoop)
Netty应用场景下:
局部串行+整体并行>一个队列+多个线程模式:
·降低用户开发难度、逻辑简单、提升处理性能
·避免锁带来的上下文切换和并发保护等额外开销
避免用锁:用ThreadLocal来避免资源争用,例如Netty轻量级的线程池实现
io.netty.util.Recycler#threadLocal
__EOF__

本文链接:https://www.cnblogs.com/LiPengFeiii/p/16179738.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~