当前位置: 首页 > news >正文

Netty源码解析-锁机制

Netty基本介绍,参考 Netty与网络编程

为了提高性能,Netty对锁也做了大量优化

1、锁优化技术

Netty大量使用了锁优化技术:

  • 1.1 减小锁粒度
  • 1.2 减少锁对象的空间占用
  • 1.3 提高锁的性能
  • 1.4 根据不同业务场景选择合适锁
  • 1.5 能不用锁则不用锁

1.1 减小锁粒度

在Netty4.1.15.Final版本中ServerBootstrap.init方法中有两个地方对对象加锁,而不是在方法上加一个大锁,缩小了锁范围,如下图
在这里插入图片描述

1.2 减少锁对象的空间占用

源码ChannelOutboundBuffer类,如下图:

totalPendingSize是用来统计待发送字节数的,上面的TOTAL_PENDING_SIZE_UPDATER是AtomicLongFieldUpdater类型的,它实现对ChannelOutboundBuffer的totalPendingSize属性进行加锁累加,实现一个类似AtomicLong的功能。(下面的unwritable一样的道理)

在这里插入图片描述

那么为什么要这么做呢?为什么不直接使用AtomicLong来定义totalPendingSize?

为了节省空间

AtomicLong  VS  long + AtomicLongFieldUpdater(帮助long完成原子操作)
类型占用空间
AtomicLong对象头16B + 8B数据 + 8引用 =至少32B
long8B
直接使用long,节省20多个字节,虽然很少,但是作为一个网络工具,在大流量的情况下可以节省出很多空间,还是很有意义的

1.3 提高锁性能

1.3.1 我们看一下PlatformDependent.LongCounter方法如何做的?

源码PlatformDependent,这个类里面有很多类似代码
在这里插入图片描述

该方法提供了一个Long类型的线程安全累加器,针对java版本8以后和8以前的提供的累加器不一样

1.8及后  LongAdder   VS  AtomicLong(1.8)

因为LongAdder是1.8版本开始增加的新的Long累加器,在高并发是性能要优于AtomicLong,所以1.8版本以后使用LongAdder

1.3.2 LongAdder和AtomicLong

  • AtomicLong 对Long类型进行原子读写
  • LongAdder将Long的值value分成若干个cell,高并发是对某个cell的值累加,可以同时对多个cell值进行累加,能支持更高的并发。需要取到value就对所有cell进行一次sum就可以了
    在这里插入图片描述

1.3.3 我们做一个简单的测试看一下LongAdder和AtomicLong的性能:

public class LongAdderTest {public static void main(String[] args) {testAtomicLongVSLongAdder(10, 10000);System.out.println("==================");testAtomicLongVSLongAdder(10, 200000);System.out.println("==================");testAtomicLongVSLongAdder(100, 200000);}//AtomicLong与LongAdder多线程并发模拟及耗时统计static void testAtomicLongVSLongAdder(final int threadCount, final int times) {try {long start = System.currentTimeMillis();testLongAdder(threadCount, times);long end = System.currentTimeMillis() - start;// System.out.println("条件>>>>>>线程数:" + threadCount + ", 单线程操作" + times);System.out.println("LongAdder--count" + (threadCount * times) + ",time:" + end);long start2 = System.currentTimeMillis();testAtomicLong(threadCount, times);long end2 = System.currentTimeMillis() - start2;System.out.println("Atomic--count" + (threadCount * times) + ",time:" + end2);} catch (InterruptedException e) {e.printStackTrace();}}//使用AtomicLong模拟i++多线程并发:threadCount线程数、times每个线程运行多少次static void testAtomicLong(final int threadCount, final int times) throws InterruptedException {CountDownLatch countDownLatch = new CountDownLatch(threadCount);//发令枪:确保多线程同时运行AtomicLong atomicLong = new AtomicLong();for (int i = 0; i < threadCount; i++) {new Thread(new Runnable() {@Overridepublic void run() {for (int j = 0; j < times; j++) {atomicLong.incrementAndGet(); //++操作}countDownLatch.countDown();}}, "my-thread" + i).start();}countDownLatch.await();}//使用LongAdder模拟i++多线程并发:threadCount线程数、times每个线程运行多少次static void testLongAdder(final int threadCount, final int times) throws InterruptedException {CountDownLatch countDownLatch = new CountDownLatch(threadCount);LongAdder longAdder = new LongAdder();for (int i = 0; i < threadCount; i++) {new Thread(new Runnable() {@Overridepublic void run() {for (int j = 0; j < times; j++) {longAdder.add(1);//是原子操作,多线程安全  //++操作}countDownLatch.countDown();}}, "my-thread" + i).start();}countDownLatch.await();}
}

运行结果

如下图,高并发情况下LongAdder性能显著高于AtomicLong
在这里插入图片描述

1.4 根据不同的业务场景选择合适的锁

SingleTreadEventExecutor中定义了Atomic…类型、CountDownLatch形式的锁在不同的地方使用
在这里插入图片描述

1.5 能不用锁就不用锁

我们Netty源码的Recycler类里面有一个属性threadLocal,他是FastThreadLocal类型,该来对jdk提高的ThreadLocal做了一层包装,该类有一个虚方法onRemoval,使用该类必须实现这个方法,避免内存泄露。

ThreadLocal是线程私有的,使用这个东西可以避免线程操作共享变量的并发竞争。
在这里插入图片描述

总结

从上面的讨论的五种锁优化技术可以看出来,Netty对锁的优化可以说做到极致,各种场景下都对锁的优化有大量使用,这也是Netty高性能的一个重要原因,这些值得我们学习在项目中使用。

相关文章:

Netty源码解析-锁机制

Netty基本介绍&#xff0c;参考 Netty与网络编程 为了提高性能&#xff0c;Netty对锁也做了大量优化 1、锁优化技术 Netty大量使用了锁优化技术&#xff1a; 1.1 减小锁粒度1.2 减少锁对象的空间占用1.3 提高锁的性能1.4 根据不同业务场景选择合适锁1.5 能不用锁则不用锁 …...

【C/C++】initializer_list

initializer_list 1 构造函数场景 class P { public:P(int a, int b) {std::cout << "int, int" << std::endl;}P(std::initializer_list<int> initList) {std::cout << "initializer_list" << std::endl;} };调用&#x…...

不要再混淆啦!一文带你学会原型链继承、构造函数继承、寄生组合继承、ES6继承

JS继承目录 一、原型链继承2、构造函数继承3、组合继承4、寄生组合继承5、ES6继承 js有几种经典的继承方式。比如 原型链继承、 构造函数继承、 组合继承、 寄生组合继承、 ES6继承。让我们一一分析并实现。同时了解每种方案的优缺点。 其实js的继承本质上是通过原型链机制…...

828华为云征文|华为云Flexus X实例Windows Server 2019安装护卫神防火墙——为企业运维安全发挥重要作用!!!

前言 公司最近需要选购一台华为云Windows服务器部署产品应用&#xff0c;但是考虑到Windows的安全性至关重要。护卫神防火墙无疑是守护Windows系统安全的得力助手。 华为云以其强大的性能和稳定的服务&#xff0c;为众多企业和开发者提供了可靠的云端基础设施。在网络环境日益复…...

最新的iOS 18版本和Android 15版本系统分别升级了哪些功能?

iOS 18 推出了多项激动人心的新功能和改进。以下是一些亮点&#xff1a; 日记应用&#xff1a;一款全新的日记应用&#xff0c;旨在帮助用户记录日常经历、想法和活动&#xff0c;利用设备内置智能功能建议主题&#xff0c;并根据照片、位置和其他数据组织条目。 眼动追踪导航…...

window系统DockerDesktop 部署windows容器

目录 参考文献1、安装Docker Desktop1.1 下载安装包1.2 安装教程1.3 异常解决 2、安装windows容器2.1 先启动DockerDesktop 软件界面2.2 检查docker版本2.3 拉取windows镜像2.4 网盘下载windows镜像 参考文献 windows容器docker中文官网 Docker: windows下跑windows镜像 1、安…...

CSDN文章导出md并迁移至博客园

一、获取所有文章地址 1.进csdn首页&#xff0c;点击自己的头像 2.在个人主页界面&#xff0c;按F12打开控制台&#xff0c;并找到network&#xff0c;找到get-business开头的请求&#xff0c;右键copy他的url 3.选择console,输入一下代码&#xff0c;其中fetch里面的url是你刚…...

计算机组成原理(笔记5原码和补码的乘法以及直接补码阵列乘法器 )

原码一位乘法 手算&#xff1a;过程 令x′|x|0.x1x2…xn-1xn&#xff0c;y′|y|0.y1y2…yn-1yn 同时令乘积P′ |P| x′ y′&#xff0c;有&#xff1a; x′ y′ x′(0.y1y2…yn-1yn) x′ (y12-1y22-2…yn-12-(n-1)yn2-n) 2-1(y1x′2-1(y2x′…2-1(yn-1x′2-1(ynx′0))…))…...

【hot100-java】【括号生成】

R9-回溯篇 枚举填左括号 class Solution {private int n;private char[] path;private final List<String> retnew ArrayList<>();public List<String> generateParenthesis(int n) {this.nn;//所有括号长度都是n*2pathnew char [n*2];dfs(0,0);return ret;…...

k8s_资源管理介绍

资源管理介绍 在k8s中&#xff0c;所有内容都抽象成资源&#xff0c;用户需要通过操作资源来管理k8s k8s本身就是一个集群系统&#xff0c;用户可以在集群中部署服务&#xff0c;在k8s集群中运行一个个的容器&#xff0c;将指定的程序部署到容器中 k8s最小的管理单元是pod&…...

操作简单 地检编码器 武汉正向科技售后优质

武汉正向科技的地检编码器以导轨式安装方式&#xff0c;方便拆卸&#xff0c;立体结构造型&#xff0c;节约空间。 格雷母线定位系统由格雷母线&#xff0c;天线箱&#xff0c;解码器&#xff0c;编码器等部件构成。 用途 地上检测方式地址信号的编码、功率放大&#xff0c;与…...

2024中国新能源汽车零部件交易会,开源网安展示了什么?

近日&#xff0c;2024中国新能源汽车零部件交易会在十堰国际会展中心举行。开源网安车联网安全实验室携车联网安全相关产品及解决方案亮相本次交易会&#xff0c;保障智能网联汽车“车、路、云、网、图、边”安全&#xff0c;推动智能网联汽车技术突破与产业化发展。 中国新能源…...

Java解析嵌套jar中class文件

一、简述 Maven项目通过package打成jar包后&#xff0c;jar包中包含所有依赖lib文件。本文介绍了两种方式解析嵌套jar中的class文件&#xff0c;一种是通过spring-boot-loader包JarFileArchive&#xff0c;另一种是util包中JarFile。 二、JarFileArchive方式 1.spring-boot-…...

【含文档】基于Springboot+Vue的高校竞赛管理系统(含源码+数据库+lw)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 系统定义了三个…...

在大模型应用层面区分对比检索增强生成RAG技术和知识库技术

在前文&#xff1a; 《RAG(Retrieval-Augmented Generation)检索增强生成技术基础了解学习与实践》 初步了解实践了RAG技术&#xff0c;后面好多朋友也在沟通聊到了前面大模型另一项技术就是本地知识库方法&#xff0c;之前基于LangChain本地知识库的方式&#xff0c;可以本地…...

云和恩墨携手华为,发布zCloud数据库备份管理一体机并宣布共建数据保护生态...

为期三天的第九届华为全联接大会&#xff08;HUAWEI CONNECT 2024&#xff09;于9月19日在上海世博中心&展览馆盛大召开。20日下午&#xff0c;一场围绕“全场景数据保护&#xff0c;护航数智化时代”的专题论坛举办&#xff0c;云和恩墨受邀参加&#xff0c;并期待与华为合…...

Linux系统备份Gitee等云git所有仓库与所有分支的数字资产

思路&#xff1a; 1. ssh 配置 2. reps.txt 列出所有仓库名 3. exp的自动化备份脚本 -- 环境安装&#xff1a; exp需要依赖安装的文件&#xff0c;所以先执行下(以ubuntu为例)&#xff1a; sudo apt-get install expect 操作步骤&#xff1a; ssh 配置 1. 添加公钥至 …...

JavaScript 条件循环语句

‌条件循环语句‌是编程中的一种控制结构&#xff0c;它允许程序根据特定条件重复执行一段代码&#xff0c;直到满足某个条件为止。这种结构通常包括条件语句和循环语句&#xff0c;它们共同作用&#xff0c;使得程序能够根据预设的条件来决定是否继续执行循环体中的代码。 fo…...

LeetCode2207解题思路

题目描述 字符串中最多数目的子序列 解题思路&#xff1a; 题目要求我们找到在 text 中 找到最多可组成 pattern 的字符串个数&#xff0c;并且允许在 text 的任意位置插入 pattern 中一个字符&#xff0c;也就是说我们只需要考虑 text 中的 pattern 含有的字符即可。例如示例…...

opencv图像增强十四:opencv两种白平衡介绍及实现

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、白平衡介绍二、灰度世界法三、完美反射法 前言 在摄影与影像领域&#xff0c;白平衡是一个至关重要的概念。它直接影响着画面的色彩表现&#xff0c;关系到…...

Linux标准IO(四)-格式化I/O输入

C 库函数提供了 3 个格式化输入函数&#xff0c;包括&#xff1a;scanf()、fscanf()、sscanf()&#xff0c;其函数定义如下所示&#xff1a; #include <stdio.h> int scanf(const char *format, ...); int fscanf(FILE *stream, const char *format, ...); int sscanf(c…...

分布式安装LNMP

目录 搭建LNMP架构 安装mysql 1.上传mysql软件包&#xff0c;关闭防火墙和核心防护 2.安装环境依赖包&#xff0c;桌面安装可能有自带的数据库除 3.配置软件模块 4.编译及安装 5.创建mysql用户 6.修改mysql 配置文件 7.更改mysql安装目录和配置文件的属主属组 8.设置…...

TFTP协议

目录 一、TFTP协议概述 1.1 TFTP协议简介 1.2 TFTP协议特点 二、TFTP协议原理 2.1 TFTP协议工作流程 2.2 TFTP协议数据包格式 三、TFTP协议应用场景 3.1 网络设备配置文件传输 3.2 虚拟机镜像文件传输 3.3 IoT设备固件升级 四、TFTP协议优化方法 4.1 增加超时重传机…...

FPGA随记-二进制转格雷码

反射二进制码&#xff08;RBC&#xff09;&#xff0c;也称为反射二进制&#xff08;RB&#xff09;或格雷码&#xff08;Gray code&#xff09;&#xff0c;得名于Frank Gray&#xff0c;是二进制数制的一种排列方式&#xff0c;使得连续两个值之间仅有一个比特&#xff08;二…...

Android常用C++特性之std::unique_lock

声明&#xff1a;本文内容生成自ChatGPT&#xff0c;目的是为方便大家了解学习作为引用到作者的其他文章中。 std::unique_lock 是 C 标准库中的一种灵活的锁管理类&#xff0c;提供了比 std::lock_guard 更多的功能和灵活性。它可以控制对互斥锁&#xff08;std::mutex&#x…...

网络与信息安全工程师(工信部教育与考试中心)

在当今数字化时代&#xff0c;大量的敏感信息与业务流程在网络上传输和处理&#xff0c;使得网络与信息安全成为保障企业运营、政务管理以及金融交易等关键领域不可忽视的一环。 因此&#xff0c;对网络安全专家的需求日益增长。 例如&#xff0c;金融机构、大型电信运营商以…...

uni-app+vue3开发微信小程序使用本地图片渲染不出来报错[渲染层网络层错误]Failed to load local image resource

我把图片放在assets里面页面通过相对路径引入。结果一直报错。 最后我把图片放在static文件夹下面。然后修改路径指向static就可以了 或者是我们必须先import 这个图片然后在使用 import banner1 from ../../assets/images/banner/banner1.png; <image :src"banner…...

Leetcode 93-复原 IP 地址

有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 ‘.’ 分隔。 例如&#xff1a;“0.1.2.201” 和 “192.168.1.1” 是 有效 IP 地址&#xff0c;但是 “0.011.255.245”、“192.168.…...

unity 中向指定的动画片段添加动画事件,并播放动画,同时获取动画片段的时长。

示例一 using UnityEngine;using System;public static class AnimationUtils{/// <summary>/// 向指定的动画片段添加动画事件&#xff0c;并播放动画&#xff0c;同时获取动画片段的时长。/// </summary>/// <param name"_animator">需要添加动画…...

JavaEE:探索网络世界的魅力——玩转UDP编程

文章目录 UDPUDP的特点UDP协议端格式校验和前置知识校验和具体是如何工作的? UDP UDP的特点 UDP传输的过程类似于寄信. 无连接: 知道对端的IP和端口号就直接进行传输,不需要建立连接.不可靠: 没有确认机制,没有重传机制,如果因为网络故障导致该段无法到达对方,UDP协议也不会…...