首页 > 其他分享 >LongAdder原理理解体会

LongAdder原理理解体会

时间:2024-09-08 23:23:16浏览次数:11  
标签:体会 同步 synchronized LongAdder 线程 实例 加锁 原理 方法

在实际应用中,选择合适的优化方法需要根据具体的业务逻辑和并发需求进行权衡和调整。这里我们针对LongAdder的优化进行说明一下,它是基于了 CAS 分段锁的思想实现的。线程去读写一个 LongAdder 类型的变量时,流程如下:




基于 Unsafe 提供的 CAS 操作 +valitale 去实现的。在 LongAdder 的父类 Striped64 中维护着一个 base 变量和一个 cell 数组,当多个线程操作一个变量的时候,先会在这个 base 变量上进行 cas 操作,当它发现线程增多的时候,就会使用 cell 数组。比如当 base 将要更新的时候发现线程增多(也就是调用 casBase 方法更新 base 值失败),那么它会自动使用 cell 数组,每一个线程对应于一个 cell ,在每一个线程中对该 cell 进行 cas 操作,这样就可以将单一 value 的更新压力分担到多个 value 中去,降低单个 value 的 “热度”,同时也减少了大量线程的空转,提高并发效率,分散并发压力。这种分段锁需要额外维护一个内存空间 cells ,不过在高并发场景下,这点成本几乎可以忽略。


我觉得可以把 LongAdder 想象成一个超市收银台系统:


base 变量:一个主收银台,所有顾客最开始都会排队在这里付款。

cell 数组:多个备用收银台,当主收银台忙不过来时,顾客会被分配到不同的备用收银台去付款。

这样做的好处是,当有大量顾客(高并发)时,大家不会都挤在一个收银台前,避免了长时间的等待,提高了结账效率。


二、回顾Java锁优化

Java 中的 synchronized 关键字和 java.util.concurrent.locks 包中的 Lock 接口(如 ReentrantLock)是两种常见的加锁方式,它们各有优缺点,针对这两种锁,JDK 自身做了很多的优化,它们的实现方式也是不同的。我们不妨进行简单的回顾一下。


(一)synchronized 关键字

synchronized 关键字给代码或者方法上锁时,都有显示或者隐藏的上锁对象。当一个线程试图访问同步代码块时,它首先必须得到锁,而退出或抛出异常时必须释放锁(注意是 synchronized 关键字的内置机制,由 Java 语言和 JVM 自动管理。我们在使用 synchronized 关键字时,无需手动编写获取和释放锁的代码,synchronized 会自动处理这些细节)。


给普通方法加锁时:锁定对象是实例对象 (this)。相同实例的 synchronized 方法之间是串行的,不同实例之间则不会互相影响。


给静态方法加锁时:锁定对象是类的 Class 对象。所有实例共享同一个类锁,因此静态 synchronized 方法在所有实例上都是串行的。


给代码块加锁时:可以指定任意对象作为锁。锁的粒度更细,可以针对不同的对象分别加锁,灵活控制并发。


synchronized 的实现依赖于 JVM 和操作系统的原语,如监视器锁和信号量。JVM 在执行同步块时,会插入相应的加锁和解锁指令。


1. monitor 锁的实现原理

synchronized 关键字在 Java 字节码中通过监视器(Monitor)指令来实现。具体来说,当 Java 编译器编译包含 synchronized 关键字的代码时,会在相应的位置插入 monitorenter 和 monitorexit 指令。JVM 在运行这些字节码时,会负责管理锁的获取和释放。


对于同步实例方法,编译器在字节码中并不会显式插入 monitorenter 和 monitorexit 指令。相反,它会在方法的访问标志(access flag)中添加 ACC_SYNCHRONIZED 标志。JVM 在调用该方法时会自动获取实例的监视器锁,并在方法返回或抛出异常时自动释放锁。

对于同步静态方法,编译器同样会在方法的访问标志中添加 ACC_SYNCHRONIZED 标志。JVM 在调用该方法时会自动获取类的监视器锁,并在方法返回或抛出异常时自动释放锁。

对于同步代码块,编译器会在进入同步块时插入 monitorenter 指令,在退出同步块时插入 monitorexit 指令。这些指令用于显式地获取和释放指定的锁对象。

现在我们直观的验证一下:


package org.zyf.javabasic.thread.lock.opti;

/**

* @program: zyfboot-javabasic

* @description: 同步方法和同步代码块的示例类,以及它们在字节码中的表现。

* @author: zhangyanfeng

* @create: 2024-06-06 07:56

**/

public class SynchronizedExample {

   private int count = 0;

   private final Object lock = new Object();

   // 同步实例方法

   public synchronized void increment() {

       count++;

   }

   // 同步静态方法

   public static synchronized void staticIncrement() {

       // 静态方法体

   }

   // 同步代码块

   public void blockIncrement() {

       synchronized (lock) {

           count++;

       }

   }



标签:体会,同步,synchronized,LongAdder,线程,实例,加锁,原理,方法
From: https://blog.51cto.com/u_16270487/11953433

相关文章

  • 最小二乘回归算法原理及Python实践
    最小二乘回归算法原理主要基于最小化误差平方和的思想,以找到数据的最佳函数匹配。以下是对其原理的详细阐述:一、基本原理最小二乘法(LeastSquaresMethod,简称LS)是一种数学优化技术,它通过最小化误差的平方和来寻找数据的最佳函数匹配。在回归分析中,最小二乘法被广泛应用于......
  • 偏最小二乘回归算法原理及Python实践
    偏最小二乘回归(PartialLeastSquaresRegression,PLS回归)是一种统计学和机器学习中的多元数据分析方法,特别适用于处理因变量和自变量之间存在多重共线性问题的情况。其原理主要可以归纳为以下几点:一.原理概述PLS回归通过投影分别将预测变量(自变量X)和观测变量(因变量Y)投......
  • 深度解析卡尔曼滤波:原理、作用与应用
    目录一、卡尔曼滤波的基本概念二、卡尔曼滤波的数学原理三、卡尔曼滤波的作用四、卡尔曼滤波的应用五、扩展:扩展卡尔曼滤波和无迹卡尔曼滤波六、总结卡尔曼滤波(KalmanFilter)是一种用于动态系统状态估计的数学算法,尤其适用于存在噪声和不确定性的环境。其广泛应用于......
  • 前端架构到底是什么意思?底层原理是什么?
    前端架构的定义前端架构是指在前端开发中,设计和组织应用程序的基本结构和组件之间的关系的方法和原则。它涉及到如何组织代码、管理数据、处理业务逻辑以及实现用户界面等方面。前端架构的目的是提高开发效率、代码可维护性、项目的可扩展性以及优化应用性能。前端架构的底层......
  • PHP提供的高级抽象和API是什么意思?底层原理是什么?
    PHP提供的高级抽象和API是PHP语言核心及其扩展库中的一系列功能和结构的集合,它们为开发者提供了丰富的工具和接口,使得开发者能够更高效地编写代码、实现功能,并减少重复性工作。高级抽象高级抽象指的是PHP语言中那些将底层实现细节隐藏起来,只暴露给开发者简洁、易用接口的概念......
  • Go语言中的RPC协议原理解析
    Go语言中的RPC协议原理解析在分布式系统中,不同的服务或组件通常运行在不同的计算机或进程上。为了实现这些服务之间的通信,我们可以使用RPC(RemoteProcedureCall,远程过程调用)协议。RPC允许我们像调用本地函数一样调用远程服务,从而简化了分布式系统中的通信复杂性。本文将详......
  • kubernetes Ingress原理
    KubernetesIngress是一种用于管理外部访问Kubernetes服务的API资源,主要用于HTTP和HTTPS流量的路由。Ingress通过提供一个统一的入口点来简化外部流量的管理。以下是Ingress的基本原理和工作机制:1.Ingress资源定义:Ingress是Kubernetes中的一种资源对象,定义了......
  • helm工作原理是什么
    Helm是Kubernetes的包管理工具,类似于Linux的APT或YUM。它允许用户定义、安装和升级应用程序在Kubernetes上的部署。以下是Helm的工作原理和核心概念:1.ChartsChart:Helm中的基本单位,是一个包含Kubernetes资源定义的打包格式。每个Chart都包含一个Chart.yaml......
  • Linux容器技术的基础原理
    Linux容器技术是一种轻量级的虚拟化解决方案,它允许在同一操作系统内核上运行多个隔离的用户空间实例。以下是Linux容器技术的基础原理:1.命名空间(Namespaces)命名空间是Linux内核提供的一种特性,允许将系统资源(如进程、网络、文件系统等)进行隔离。容器通过使用不同的命名空间......
  • Sora原理详解
    重磅推荐专栏:《大模型AIGC》《课程大纲》《知识星球》本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和StableDiffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经验......