Netty锁事的五个关键点:
① 在意锁的对象和范围 --> 减少粒度
② 注意锁的对象本身大小 --> 减少空间占用
③ 注意锁的速度 --> 提高速度
④不同场景选择不同的并发类 -->因需而边
⑤衡量好锁的价值 --> 能不用则不用
接下来按个看看:
①:在Netty的ServerBootstrap中的init():
上图不难看出来,多处使用了synchronized(){},而并非在inti方法上使用synchronized,如果这么做那么锁的对象就是这个实例,锁的范围则是大括号方法的范围,但是实际上我们不需要这么做,只是把Synchronized method -->Synchronized block,针对上图不同的属性,我们可以分别做锁,这样就减少了锁的范围。
②:例在ChannelOutboundBuffer中有这样的代码:
这个totalPendingSize是统计待发送的字节数
这样的两个步骤直接使用原子类就能完成,为什么不用原子类而是用了两个较为复杂的方式完成!这里可以参考https://www.cnblogs.com/-qilin/p/11725861.html
③例记录内存分配字节数等功能用到的LongCounter,在PlatformDependent的newLongCounter()中
上图的代码就是筛选jdk版本然后有不同的返回类型,如果大于等于8则是LongAdderCounter;而LongAdderCounter继承java.util.concurrent.atomic.LongAdder;
package io.netty.util.internal; import java.util.concurrent.atomic.LongAdder; final class LongAdderCounter extends LongAdder implements LongCounter { @Override public long value() { return longValue(); } }
高并发时:java.util.concurrent.atomic.AtomicLong ->java.util.concurrent.atomic.LongAdder,特定场景下是优于AtomicLong ;