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

JAVA 锁—— synchronized

在这里插入图片描述

32 位机器上java对象头中,markWord 示意图如上所示,64 位机器扩展前面标识位数,如 hashcode(25 -> 31),线程ID(23 -> 54)

如果启用了偏向锁:

  • synchronized添加偏向锁:只有1个线程加锁的情况下,此时一定没有竞争
  • synchronized添加轻量级锁:超过1个线程,且交替加锁,此时没有竞争
  • synchronized添加重量级锁:超过1个线程,同时加锁,或加锁时,其它线程没释放锁,此时发生了竞争

一、基本概念

注:下面代码大部分基于 JDK 8 分析,后续有 JDK23 的分析。

1、偏向锁

为方便观察 Java 内存对象,我们使用JOL工具,详见Java对象的内存分布(一)。

1.1、代码

	/***  程序运行前最好等待5秒,开启偏向锁。*  因为 jvm 启动也有加锁需求,防止 jvm 启动时受偏向锁影响,比如锁升级带来消耗,*  故而 jvm 完全启动后(大约4s,通过参数 -XX:BiasedLockingStartupDelay=0 进行调整),才会应用偏向锁。*/public static  void main(String[] args) throws Exception{Thread.sleep(5000l); Object lock = new Object();System.out.println("---第一次----");System.out.println("加锁前:" + ClassLayout.parseInstance(lock).toPrintable());synchronized (lock) {System.out.println("加锁中:" + ClassLayout.parseInstance(lock).toPrintable());}System.out.println("加锁后:" + ClassLayout.parseInstance(lock).toPrintable());System.out.println("---第二次----");System.out.println("加锁前:" + ClassLayout.parseInstance(lock).toPrintable());synchronized (lock) {System.out.println("加锁中:" + ClassLayout.parseInstance(lock).toPrintable());}System.out.println("加锁后:" + ClassLayout.parseInstance(lock).toPrintable());}

1.2 运行结果

在这里插入图片描述

  • 大端模式:高位字节存放于内存的低地址端,低位字节存放于内存的高地址端,便于人类阅读。
  • 小端模式:低位字节存放于内存的低地址端,高位字节存放于内存的高地址端,便于机器处理。
存储模式示例(0x12345678)
大端(Big-Endian)0x12 0x34 0x56 0x78
小端(Little-Endian)0x78 0x56 0x34 0x12

1.3、注意事项

Object.hashCode()方法和System.identityHashCode()会让对象不能使用偏向锁,所以如果想使用偏向锁,那就最好重写hashCode方法。

  • 无锁和偏向锁占用相同位置,不像轻量级锁和重量级锁可以将原位置信息拷贝到其它地方进行备份,所以当对象已经存储了hashcode之后,加锁时会跳过偏向锁。
  • 偏向锁不会释放,即解锁后,锁对象头MarkWord不变。
  • JDK [6, 15),偏向锁默认开启,从 JDK 15 开始,默认关闭,可以通过 -XX:+UseBiasedLocking 开启,从JDK 18 开始彻底移除偏向锁。

2、轻量级锁

2.1、代码

	/*** 开启偏向锁后,2个线程交替加锁,偏向锁升级为轻量级锁。*/public static  void main(String[] args) throws Exception{Thread.sleep(5000l); // 等待5秒,开启偏向锁Object lock = new Object();System.out.println("---第一次----");System.out.println("加锁前:" + ClassLayout.parseInstance(lock).toPrintable());synchronized (lock) {System.out.println("加锁中:" + ClassLayout.parseInstance(lock).toPrintable());}System.out.println("加锁后:" + ClassLayout.parseInstance(lock).toPrintable());System.out.println("---第二次----");Thread thread = new Thread(() -> {synchronized (lock) {System.out.println("线程2:");System.out.println("加锁中:" + ClassLayout.parseInstance(lock).toPrintable());}System.out.println("线程2:");System.out.println("加锁后:" + ClassLayout.parseInstance(lock).toPrintable());});thread.start();}

2.2、运行结果

在这里插入图片描述

2.3、锁细节

轻量级锁加锁时,markWord中会存储指向栈中锁记录的指针,栈中锁记录存储的就是未加锁时原来的markWord,解锁时方便还原回去。

假如markWord中存储了hashcode,使用时先访问markWord发现加了轻量级锁,顺着栈指针找到栈中锁记录,即可找到hashcode


3、重量级锁

3.1、代码

    public static  void main(String[] args) throws Exception{Thread.sleep(5000l); // 等待5秒,开启偏向锁Object lock = new Object();System.out.println("---第一次----");System.out.println("加锁前:" + ClassLayout.parseInstance(lock).toPrintable());synchronized (lock) {System.out.println("加锁中:" + ClassLayout.parseInstance(lock).toPrintable());}System.out.println("解锁后:" + ClassLayout.parseInstance(lock).toPrintable());System.out.println("---第二次----");Thread thread2 = new Thread(() -> {synchronized (lock) {System.out.println("线程2:[" + Thread.currentThread() +  "] 加锁中:" + ClassLayout.parseInstance(lock).toPrintable());try {Thread.sleep(5000L); // 这里持锁5s,确保线程3加锁发生竞争;} catch (java.lang.Exception e) {}}});Thread thread3 = new Thread(() -> {synchronized (lock) {System.out.println("线程3:[" + Thread.currentThread() +  "] 加锁中:" + ClassLayout.parseInstance(lock).toPrintable());}});thread2.start();thread3.start();Thread.sleep(8000L); // 等待8s,确保线程锁释放;System.out.println("解锁后:" + ClassLayout.parseInstance(lock).toPrintable());}

3.2、运行结果

在这里插入图片描述

3.3、Monitor

  • 偏向锁、轻量级锁只要发生竞争,就会升级为重量级锁,注意,这里一步到位,不会自旋。

  • 升级为重量级锁后,其它线程自旋多次失败后,会进入 cxq 列表(相当于栈)中自旋,自旋达到阈值后,仍未获取锁,则进入阻塞状态。

  • 重量级锁加锁时,markWord中会存储指向 Monitor 的指针,Monitor 会存储未加锁时原来的markWord,解锁后还原回去。【JDK8实验如此,JDK23实验不一样】

    假如markWord中存储了hashcode,使用时先访问markWord发现加了重量级锁,顺着重量级锁指针找到Monitor,即可找到hashcode

截止目前为止,上述代码均在 JDK 8上讨论;下面讨论 JDK23

  • 重量级锁加锁时,markWord中会存储指向 Monitor 的指针,Monitor 会存储未加锁时原来的markWord,解锁时markWord不变。【JDK23实验,代码不变,运行结果如下图所示】
    在这里插入图片描述
ObjectMonitor细节如下:

在这里插入图片描述

由上图可知, wait()notify()notifyAll() 只能在重量级锁中调用,换言之,在偏向锁和轻量级锁中调用这3个方法时,会升级为重量级锁。

CAS详见CAS基础概念。


3.4、重量级锁会降级为轻量级锁吗?

    public static  void main(String[] args) throws Exception{Thread.sleep(5000l); // 等待5秒,开启偏向锁Object lock = new Object();System.out.println("---第一次----");System.out.println("加锁前:" + ClassLayout.parseInstance(lock).toPrintable());synchronized (lock) {System.out.println("加锁中:" + ClassLayout.parseInstance(lock).toPrintable());}System.out.println("解锁后:" + ClassLayout.parseInstance(lock).toPrintable());System.out.println("---第二次----");Thread thread2 = new Thread(() -> {synchronized (lock) {System.out.println("线程2:[" + Thread.currentThread() +  "] 加锁中:" + ClassLayout.parseInstance(lock).toPrintable());try {Thread.sleep(5000L); // 这里持锁5s,确保线程3加锁发生竞争;} catch (java.lang.Exception e) {}}});Thread thread3 = new Thread(() -> {synchronized (lock) {System.out.println("线程3:[" + Thread.currentThread() +  "] 加锁中:" + ClassLayout.parseInstance(lock).toPrintable());}});thread2.start();thread3.start();Thread.sleep(8000L); // 等待8s,确保线程锁释放;System.out.println("解锁后:" + ClassLayout.parseInstance(lock).toPrintable());Thread thread4 = new Thread(() -> {synchronized (lock) {System.out.println("线程4:[" + Thread.currentThread() +  "] 加锁中:" + ClassLayout.parseInstance(lock).toPrintable());}});thread4.start();

【JDK 8 重量级锁会降级为轻量级锁】

在这里插入图片描述

【JDK 23 重量级锁不会降级为轻量级锁】

在这里插入图片描述


二、补充知识

1、hashcode对锁的影响

1.1、偏向锁状态中,首次调用锁的hashcode后,偏向锁会直接升级为重量级锁。

    public static  void main(String[] args) throws Exception{Thread.sleep(5000l); // 等待5秒,开启偏向锁Object lock = new Object();System.out.println("---第一次----");System.out.println("加锁前:" + ClassLayout.parseInstance(lock).toPrintable());synchronized (lock) {System.out.println("加锁中-未调用hashcode :" + ClassLayout.parseInstance(lock).toPrintable());lock.hashCode();System.out.println("加锁中-已调用hashcode:" + ClassLayout.parseInstance(lock).toPrintable());}System.out.println("解锁后:" + ClassLayout.parseInstance(lock).toPrintable());}

在这里插入图片描述

1.2、轻量级锁状态中,首次调用锁的hashcode后,锁升级为重量级锁?

    public static  void main(String[] args) throws Exception{Object lock = new Object();System.out.println("---第一次----");System.out.println("加锁前:" + ClassLayout.parseInstance(lock).toPrintable());synchronized (lock) {System.out.println("加锁中-未调用hashcode :" + ClassLayout.parseInstance(lock).toPrintable());lock.hashCode();System.out.println("加锁中-已调用hashcode:" + ClassLayout.parseInstance(lock).toPrintable());}System.out.println("解锁后:" + ClassLayout.parseInstance(lock).toPrintable());}

【JDK 8 升级重量级锁】

在这里插入图片描述
【JDK 23 维持轻量级锁】
在这里插入图片描述


唯一不变就是变化,JDK也在不断的演进,昨天还正确的观点,今天就错误了;今天错误的观点也可能明天就正确了。

所以看到任何观点,都要保持怀疑态度啊,每个人都有自己的观点,切忌坐井观天,故步自封,一定要跳出去,用发展的视角看问题。

相关文章:

JAVA 锁—— synchronized

32 位机器上java对象头中,markWord 示意图如上所示,64 位机器扩展前面标识位数,如 hashcode(25 -> 31),线程ID(23 -> 54) 如果启用了偏向锁: synchronized添加偏向锁:只有1个线程加锁的情况下&#…...

游戏引擎学习第274天:基于弹簧的动态动画

回顾前一天内容,并为今天的工作设定目标 我们昨天展示了一些内容,现在先回顾一下昨天的进展。我们目前正在处理的是角色跳跃的动画——特别是身体部分的跳跃。 现在角色的动画状态如下: 正在实现角色的移动和跳跃。跳跃中已经加入了一些预备…...

【英语笔记(二)】句子成分、基本句型;简单描述十大词类与从句的分类、助动词和非谓语动词的使用

1. 介词 at, in, on 的用法区别 1.1 表示时间的区别 1. 表示时间的某一点、某一时刻或年龄等用 at。如: I get up at six in the morning. 我早上六点钟起床。He got married at the age of 25. 他 25 岁结婚。 2. 泛指一般意义的上午、下午或晚上以及月或年等较…...

TAPIP3D:持久3D几何中跟踪任意点

简述 在视频中跟踪一个点(比如一个物体的某个特定位置)听起来简单,但实际上很复杂,尤其是在3D空间中。传统方法通常在2D图像上跟踪像素,但这忽略了物体的3D几何信息和摄像机的运动,导致跟踪不稳定&#xf…...

RabbitMQ的工作队列模式和路由模式有什么区别?

RabbitMQ 的工作队列模式(Work Queues)和路由模式(Routing)是两种不同的消息传递模式,主要区别在于消息的分发逻辑和使用场景。以下是它们的核心差异: 1. 工作队列模式(Work Queues&#xff09…...

armv7 backtrace

ref: ARM Cortex-M3/M4/M7 Hardfault异常分析_arm hardfault-CSDN博客...

Python并发编程:开启性能优化的大门(7/10)

1.引言 在当今数字化时代,Python 已成为编程领域中一颗璀璨的明星,占据着编程语言排行榜的榜首。无论是数据科学、人工智能,还是 Web 开发、自动化脚本编写,Python 都以其简洁的语法、丰富的库和强大的功能,赢得了广大…...

泰勒展开式

常用的 泰勒展开式(Taylor series expansion)是指把一个函数在某点的邻域内展开成幂级数的形式。以函数 f ( x ) f(x) f(x) 在点 a a a 处展开为例,其泰勒展开式为: f ( x ) f ( a ) f ′ ( a ) ( x − a ) f ′ ′ ( a ) 2 …...

深入理解 Polly:.NET Core 中的健壮错误处理策略

在现代软件开发中,错误处理是构建高可用、健壮系统的关键之一。尤其是当应用依赖外部服务(如 API、数据库或其他网络资源)时,临时的服务中断、超时或其他不可预见的错误都会影响应用的稳定性。为了提升系统的容错能力,…...

【Bootstrap V4系列】学习入门教程之 组件-巨幕(Jumbotron)和列表组(List group)

Bootstrap V4系列 学习入门教程之 组件-巨幕(Jumbotron)和列表组(List group) 一、巨幕(Jumbotron)1.1 带有圆角1.2 全宽且无圆角 二、列表组(List group)2.1 Basic example2.2 Acti…...

02.three官方示例+编辑器+AI快速学习webgl_animation_skinning_blending

本实例主要讲解内容 这个示例展示了Three.js中骨骼动画混合(Skeletal Animation Blending)的实现方法,通过加载一个士兵模型,演示了如何在不同动画状态(如站立、行走、跑步)之间进行平滑过渡。核心技术包括动画混合器(AnimationM…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1商用服务开通教程以及模型体验

在当今数字化浪潮迅猛推进的时代,云计算与人工智能技术的深度融合正不断催生出众多创新应用与服务,为企业和个人用户带来了前所未有的便利与发展机遇。本文将重点聚焦于在华为云这一行业领先的云计算平台上,对 DeepSeek-V3/R1 商用服务展开的…...

大语言模型通过MCP控制STM32-支持Ollama、DeepSeek、openai等

MCP控制STM32 MCP部分 1.下载源码 git clone https://github.com/ana52070/MCP_Control_STM32.git cd MCP_Control_STM32 cd mcp-led_oled2. 创建并激活虚拟环境 为了避免不同项目之间的依赖冲突,建议使用虚拟环境。根据你的操作系统和 Python 版本,…...

Linux-Ubuntu安装Stable Diffusion Forge

SD Forge在Win上配置起来相对简单且教程丰富,而在Linux平台的配置则稍有门槛且教程较少。本文提供一个基于Ubuntu24.04发行版(对其他Linux以及SD分支亦有参考价值)的Stable Diffusion ForgeUI安装配置教程,希望有所帮助 本教程以N…...

LoRA(Low-Rank Adaptation)原理详解

LoRA(Low-Rank Adaptation)原理详解 LoRA(低秩适应)是一种参数高效微调(Parameter-Efficient Fine-Tuning, PEFT)技术,旨在以极低的参数量实现大模型在特定任务上的高效适配。其核心思想基于低秩分解假设,即模型在适应新任务时,参数更新矩阵具有低秩特性,可用少量参…...

分享一个可以用GPT打标的傻瓜式SD图片打标工具——辣椒炒肉图片打标助手

一、打标效果展示 请参考下图,了解最终的打标效果: 打标速度提升百分之300; 打标成本: gpt4o每百张图约5毛rmb; gpt4o-mini价格更低; 更有claude,grok,gemini,豆包等…...

实战项目2(03)

目录 任务场景一【重点】 【sw1配置】 【sw2配置】 任务场景二【重点】 【sw1配置】 【sw2配置】 【sw3配置】 任务场景一【重点】 掌握基于SVI实现跨VLAN通信——某公司网络为了减少广播包对网络的影响,网络管理员对网络进行了VLAN划分,完成VLA…...

PyCharm软件下载和配置Python解释器

以下是详细的PyCharm下载及解释器环境配置步骤: 有什么问题可以留评论(看见会回复的) 一、PyCharm下载 1. 访问官网 进入JetBrains官网:https://www.jetbrains.com/pycharm/ 2. 选择版本 Community版(免费&…...

《从零构建一个简易的IOC容器,理解Spring的核心思想》

大家好呀!今天我们要一起探索Java开发中最神奇的魔法之一 —— Spring框架的IOC容器!🧙‍♂️ 我会用最最最简单的方式,让你彻底明白这个看似高深的概念。准备好了吗?Let’s go! 🚀 一、什么是IOC容器&…...

差分与位移算子

差分与位移算子是数值分析和离散数学中处理序列或离散函数的重要工具。它们通过算子代数简化差分的计算和分析,以下是关键概念和关系的总结: 1. 位移算子(Shift Operator) 定义: 位移算子 ( E ) 将函数 ( f(x) ) 沿自变…...

Robot之VideoMimic:《Visual Imitation Enables Contextual Humanoid Control》翻译与解读

Robot之VideoMimic:《Visual Imitation Enables Contextual Humanoid Control》翻译与解读 导读:这篇论文介绍了VIDEOMIMIC,一个基于视觉模仿的真实到模拟到真实流水线,用于训练人形机器人执行上下文相关的全身动作。该方法通过分…...

【Java学习日记34】:this关键字和成员变量

为什么不需要加 this? 作用域规则: Java编译器在查找变量时遵循“就近原则”。 先在当前方法内查找局部变量或参数。 若找不到,则去类的成员变量中查找。 getName() 的上下文: 该方法没有参数或局部变量名为 name,因…...

包名查看器APP:高效管理手机应用的实用工具

包名查看器APP是一款功能强大的文件查看软件,专为安卓用户设计,能够帮助用户快速了解手机上安装和未安装的APK包信息。作为酷安首发的APK信息查看工具,它提供了比系统设置更详细的信息,如版本号、包名、MD5等,帮助用户…...

左右括号的最小处理次数

1、题目描述 多多君在处理一个由左结号(和右语号&#xff09;组成的字符串&#xff0c;多多君每次处理时可以顺序读取一个字符或者一个有效括号子串&#xff0c;求问多多的最小处理次数。 输入描述&#xff1a; 第一行为一个整数N&#xff0c;表示字符串长度&#xff08;1<…...

22.第二阶段x64游戏实战-分析周围对象类型

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 本次游戏没法给 内容参考于&#xff1a;微尘网络安全 上一个内容&#xff1a;21.第二阶段x64游戏实战-分析采集物偏移 上一个内容里发现采集物的名字通过我们…...

【C/C++】无符号调试:GDB解栈实战指南

文章目录 无符号调试&#xff1a;GDB解栈实战指南1 生成并加载 Core Dump2 查看原始堆栈信息&#xff08;地址形式&#xff09;3 确认加载的共享库地址范围4 手动转换地址为函数名5 反汇编关键代码段6 加载外部符号文件&#xff08;如有&#xff09;7 结合系统库文档分析8 示例…...

梦熊联盟:202505基础语法-题解

202505基础语法-题解 T1 - 九的倍数 解法&#xff1a; 对于 9 的倍数&#xff0c;只需要判定其各位的数码和是否为 9 的倍数即可。 例如判断一个数是不是 9 的倍数&#xff0c;只要判断其各位数字之和是不是 9 的倍数&#xff0c;因为一个数能被 9 整除当且仅当它的各位数字之和…...

Java SE(11)——内部类

1.内部类 定义&#xff1a;Java中的内部类(Inner Class)是指在一个类的内部定义的类。 使用场景&#xff1a;当一个类的内部&#xff0c;存在一个部分需要完成的结构进行描述&#xff0c;而该内部结构只为外部类提供服务&#xff0c;那么这个内部结构就可以使用内部类&#xff…...

优化审核模块响应时间从8s降至1.2s的数据库解决方案

优化审核模块响应时间从8s降至1.2s的数据库解决方案 要优化审核模块的数据库性能&#xff0c;需要从多个层面进行分析和优化。以下是具体的SQL语句设计和优化方案&#xff1a; 1. 分析当前性能瓶颈 首先需要找出慢查询&#xff1a; -- 查看慢查询日志中的审核模块相关查询 …...

YOLO-World:基于YOLOv8的开放词汇目标检测

文章目录 前言1、出发点2、方法2.1.TextEncoder2.2.ReparmVLPAN2.3.输出头 3、实验3.1.数据集3.2.LVIS测试集 总结 前言 本文介绍一篇来自腾讯的开放词汇检测工作&#xff0c;发表自CVPR2024&#xff0c;论文链接&#xff0c;开源地址。 1、出发点 GroundingDINO在开放词汇检测…...

NX989NY104美光科技芯片NY109NY113

NX989NY104美光科技芯片NY109NY113 存储市场新势力&#xff1a;美光科技的崛起与技术突围 在半导体行业波澜壮阔的浪潮中&#xff0c;美光科技宛如一颗璀璨的明珠&#xff0c;以其独特的技术实力和敏锐的市场洞察力&#xff0c;在存储领域占据了重要的一席之地。尤其是其旗下…...

LabVIEW的PID参数自适应控制

在工业控制领域&#xff0c;PID 控制凭借结构简单、稳定性好、工作可靠等优点被广泛应用。然而&#xff0c;传统固定参数的 PID 控制在面对复杂多变的工况时&#xff0c;控制效果往往难以达到最优。基于 LabVIEW 实现 PID 控制根据情况选择参数&#xff08;即参数自适应调整&am…...

Quartus与Modelsim-Altera使用手册

目录 文章内容&#xff1a; 视频内容&#xff1a; Quartus&#xff1a; ModelSim&#xff1a; 顶层设计与子模块&#xff1a; 只是对所查阅的相关文章的总结与视频总结 文章内容&#xff1a; 这篇对基础操作很详细&#xff1a; 一、Quartus II软件的使用_quartus2软件上…...

设计模式之工厂模式(二):实际案例

设计模式之工厂模式(一) 在阅读Qt网络部分源码时候&#xff0c;发现在某处运用了工厂模式&#xff0c;而且编程技巧也用的好&#xff0c;于是就想分享出来&#xff0c;供大家参考&#xff0c;理解的不对的地方请多多指点。 以下是我整理出来的类图&#xff1a; 关键说明&#x…...

数据可视化大屏——智慧社区内网比对平台

综述分析&#xff1a; 智慧社区内网数据比对信息系统 这段代码实现了一个智慧社区内网数据比对信息系统的前端界面&#xff0c;采用三栏式布局展示各类社区安全相关数据。界面主要由左侧数据统计、中间地图展示和右侧数据分析三部分组成&#xff0c;使用了多种图表可视化技术…...

Spark任务调度流程详解

1. 核心调度组件 DAGScheduler&#xff1a;负责将Job拆分为Stage&#xff0c;处理Stage间的依赖关系。 TaskScheduler&#xff1a;将Task分配到Executor&#xff0c;监控任务执行。 SchedulerBackend&#xff1a;与集群管理器&#xff08;如YARN、K8s&#xff09;通信&#x…...

LeetCode 215题解 | 数组中的第K个最大元素

数组中的第K个最大元素 一、题目链接二、题目三、算法原理四、编写代码 一、题目链接 数组中的第K个最大元素 二、题目 三、算法原理 法一&#xff1a;排序 法二&#xff1a;优先级队列&#xff08;堆&#xff09; 重点看法二&#xff1a; 默认建大堆&#xff0c;意味着以…...

探秘 Cursor 核心:解锁系统提示词的进阶之路

在 AI 编程领域&#xff0c;Cursor 无疑是一颗耀眼的明星&#xff0c;其母公司 Anysphere 在短短三个月内&#xff0c;估值从 25 亿美元狂飙至 100 亿美元&#xff0c;这样的发展速度令人咋舌。而 Cursor 强大功能背后的核心 —— 系统提示词&#xff0c;始终笼罩着一层神秘的面…...

ElasticSearch入门详解

1.ElasticSearch 1.1 ElasticSearch(简称es) Elasticsearch是用Java开发并且是当前最流行的开源的企业级搜索引擎。 能够达到实时搜索&#xff0c;稳定&#xff0c;可靠&#xff0c;快速&#xff0c;安装使用方便。 客户端支持Java、.NET&#xff08;C#&#xff09;、PHP、Py…...

【计算机网络01】 网络组成与三种交换方式

【参考资料】 《自顶向下的计算机网络第八版》湖科大计算机网络&#xff08;b站&#xff09;王道考研&#xff08;b站&#xff09; 文章目录 一、网络基础概念解析1.1 网络、互联网与因特网 二、因特网发展三阶段&#xff08;了解&#xff09;三、ISP3.1 ISP基本概念3.2 基于I…...

计算机网络——以太网交换机

目录 交换机的作用 以太网交换机的自学习功能 因为以太网交换机有自学习功能&#xff0c;所以以太网交换机支持即插即用 交换机的作用 它工作在数据链路层&#xff0c;为结点转发帧&#xff0c;并且可以根据一个帧的目的MAC地址去进行相应的转发&#xff0c;以及交换机的每…...

机器视觉开发教程——C#如何封装海康工业相机SDK调用OpenCV/YOLO/VisionPro/Halcon算法

目录 引言前期准备Step1 创建工程Step2 创建接口2.1定义操作相机实例接口方法2.2定义设置相机参数接口方法&#xff08;部分&#xff09; Step3 创建基类3.1定义操作相机实例&&设置相机参数的抽象层3.2定义操作相机实例&&设置相机参数的公用方法1.获取当前帧图…...

c++STL-string的模拟实现

cSTL-string的模拟实现 string的模拟实现string的模拟线性表的实现构造函数析构函数获取长度&#xff08;size&#xff09;和获取容量&#xff08;capacity&#xff09;访问 [] 和c_str迭代器&#xff08;iterator&#xff09;交换swap拷贝构造函数赋值重载&#xff08;&#x…...

HTTP 和 WebSocket 的区别

✅ 一、定义对比 协议简要定义HTTP一种基于请求-响应模式的、无状态的应用层协议&#xff0c;通常用于客户端与服务器之间的数据通信。WebSocket一种全双工通信协议&#xff0c;可以在客户端和服务器之间建立持久连接&#xff0c;实现实时、低延迟的数据传输。 ✅ 二、通信方式…...

【Tools】Visual Studio使用经验介绍(包括基本功能、远程调试、引入第三方库等等)

这里写目录标题 1. VS基本使用1.1. 快捷键1.2. 查看变量地址1.3. 查看代码汇编1.4. visual studio 热重载功能的使用1.5. vs远程服务器调试1.6. 引入第三方库VLD1.7. release debug模式 1. VS基本使用 1.1. 快捷键 ctrl c :复制光标所在行 注意&#xff1a;只需要光标在这…...

一周内学完计算机网络课程之二:计算机网络物理层的理解

消失人口回归&#xff0c;重新开始学习新知识。再次伟大。 物理层详解 需要理解的几个概念&#xff1a; 曼彻斯特编码、差分曼彻斯特编码 码元&#xff1a;构成信号的基本单元 调制&#xff1a; 通信中的调制是一种将原始信号&#xff08;如音频、视频、数据等&#xff09;转…...

Python OpenCV性能优化与部署实战指南

在计算机视觉领域&#xff0c;OpenCV作为开源视觉库的标杆&#xff0c;其性能表现直接影响着从工业检测到AI模型推理的各类应用场景。本文结合最新技术趋势与生产实践&#xff0c;系统性梳理Python环境下OpenCV的性能优化策略与部署方案。 一、性能优化核心技术矩阵 1.1 内存…...

深度解析:可视化如何重塑销售策略制定与执行

为什么你的销售策略总是“听起来挺对&#xff0c;做起来却没用”&#xff1f; 你有没有遇到过这样的情况&#xff1a; 销售团队天天跑客户&#xff0c;但业绩还是上不去&#xff1b;市场部说数据在增长&#xff0c;销售部却觉得“根本没转化”&#xff1b;高层开会时信心满满…...

opencv关键点检测

python 使用opencv进行图片关键点检测 功能&#xff1a; 在一张图片中裁剪出一块小图 使用cv2中 cv2.SIFT_create() SIFT检测器检测关键点 匹配原图和小图的关键点 import cv2 import numpy as np # 读取图像 img1 cv2.imread(rE:\234947.jpg, cv2.IMREAD_GRAYSCALE) img…...

C#游戏开发中的注意事项

目录 一、性能优化:提升游戏运行效率 1. 避免不必要的循环和迭代 2. 减少字符串拼接 3. 利用Unity的生命周期函数 4. 使用对象池(Object Pooling) 二、内存管理:避免内存泄漏和资源浪费 1. 及时释放非托管资源 2. 避免空引用异常 3. 合理使用引用类型和值类型 4. …...