Java高并发累加器Striped64

article/2025/9/19 1:57:33

原子类

在多线程环境下,常用累加操作方式是使用原子类进行累加,例如AtomicInteger、AtomicLong。但是使用原子类在多线程高竞争的情况下,CAS会经常失败,并发效率会大大降低。
在这里插入图片描述
因为CAS操作失败后要自旋再次进行替换,这样失败的线程就会大量消耗CPU资源。所以在高并发的场景下使用原子类累加器并不是很好的选择。

Striped64

Striped64是一种高并发累加器,有效解决了原子类累加的弊端。Striped64将线程竞争的操作分散开来,每个线程操作一个cell,而sum则等于base和所有cell值的和。

性能比较

开启10个线程,并发执行累加操作,每个线程加10000000。

  1. 使用AtomicLong
public static void main(String[] args) {AtomicLong atomicLong = new AtomicLong(0);CyclicBarrier cyclicBarrier = new CyclicBarrier(10);CountDownLatch countDownLatch = new CountDownLatch(10);long l = System.currentTimeMillis();for (int i=0;i<10;i++){new Thread(new Runnable() {@Overridepublic void run() {try {cyclicBarrier.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}int i=10000000;while(i>0){atomicLong.incrementAndGet();i--;}countDownLatch.countDown();}}).start();}try {countDownLatch.await();long l2 = System.currentTimeMillis();System.out.println(l2-l);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(atomicLong.get());}

计算结果:

1964ms
100000000
  1. 使用LongAdder
public static void main(String[] args) {LongAdder longAdder = new LongAdder();CyclicBarrier cyclicBarrier = new CyclicBarrier(10);CountDownLatch countDownLatch = new CountDownLatch(10);long l = System.currentTimeMillis();for (int i=0;i<10;i++){new Thread(new Runnable() {@Overridepublic void run() {try {cyclicBarrier.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}int i=10000000;while(i>0){longAdder.add(1);i--;}countDownLatch.countDown();}}).start();}try {countDownLatch.await();long l2 = System.currentTimeMillis();System.out.println((l2-l)+"ms");} catch (InterruptedException e) {e.printStackTrace();}System.out.println(longAdder.sum());}

执行结果:

266ms
100000000

比较两者的性能,Striped64比原子类要快约10倍。

LongAdder

在这里插入图片描述
当线程来进行添加操作的,会根据线程ID定位到具体的cell,线程再对cell进行CAS操作,进行累加。这样各个线程就不用产生激烈竞争导致频繁CAS失败。对于JVM中最高并发线程数等与机器可用CPU核数,所以cells数组的长度也不会很长,进行数组求和也很快。
在这里插入图片描述
Striped64的继承类有LongAdder,以LongAdder累加流程为例:
在这里插入图片描述


http://chatgpt.dhexx.cn/article/lRHLhfmS.shtml

相关文章

Java高并发编程实战8,同步容器与并发容器

目录 一、为什么这种方式不能实现线程安全性?二、组合三、同步容器类四、隐藏迭代器五、并发容器六、ConcurrentHashMap一、为什么这种方式不能实现线程安全性? 分析一段代码: package com.guor.util;import java.util.

Java高并发项目案例,Java开发指南

一、前言 最近刚读完一本书&#xff1a;《Netty、Zookeeper、Redis 并发实战》&#xff0c;个人觉得 Netty 部分是写得很不错的&#xff0c;读完之后又对 Netty 进行了一波很好的复习&#xff08;之前用 spring boot netty zookeeper 模仿 dubbo 做 rpc 框架&#xff0c;那时…

Java高并发三部曲

疯狂创客圈为小伙伴奉上以下珍贵的学习资源&#xff1a; 疯狂创客圈 经典极品 &#xff1a; 极致经典《 Java 高并发 三部曲 》 面试必备 大厂必备 涨薪必备 疯狂创客圈 经典图书 &#xff1a; 《Netty Zookeeper Redis 高并发实战》 面试必备 大厂必备 涨薪必备 免费领 …

java队列处理高并发_Java高并发--消息队列

Java高并发--消息队列 举个例子&#xff1a;在购物商城下单后&#xff0c;希望购买者能收到短信或者邮件通知。有一种做法时在下单逻辑执行后调用短信发送的API&#xff0c;如果此时服务器响应较慢、短信客户端出现问题等诸多原因购买者不能正常收到短信&#xff0c;那么此时是…

Java如何解决高并发的问题? 可以试试这些方法

大家好&#xff0c;我是小武&#xff0c;一个工作10年的程序员&#xff0c;就职于鹅厂&#xff0c;平时喜欢搞搞副业。 在工作中&#xff0c;我们经常会遇到高并发的问题&#xff0c;这个是很常见的&#xff0c;只要用户访问量一多的情况下&#xff0c;那么我们的网站就会变慢&…

单例模式的五种写法

设计模式&#xff08;Design pattern&#xff09;&#xff0c;提供了在软件开发过程中面临的一些问题的最佳解决方案&#xff0c;是Java开发者必修的一门课程。主要分创建型模式、结构型模式和行为型模式。其中接下来我们要写的是单例模式&#xff0c;属于创建型模式。 单例模式…

JAVA单例模式代码实现

JAVA常见的设计模式之单例模式 懒汉模式 懒汉式是典型的时间换空间&#xff0c;也就是每次获取实例都会进行判断&#xff0c;看是否需要创建实例&#xff0c;浪费判断的时间。当然&#xff0c;如果一直没有人使用的话&#xff0c;那就不会创建实例&#xff0c;则节约内存空间(…

单例模式编写

单例">什么是单例 单例是保证一个内存/进程里只有一个类的实例&#xff0c;并提供一个访问它的全局访问点。 内存/进程中只有一个实例线程安全性能优化防止序列化产生新对象 写一个单例模式 1、饿汉模式 public class Singleton {//饿汉模式private static Single…

设计模式——单例模式八种方式实现与分析(附代码示例)

一. 概念 所谓类的单例设计模式&#xff0c;就是采取一定的方法保证在整个的软件系统中&#xff0c;对某个类只能存在一个对象实例&#xff0c;并且该类只提供一个取得其对象实例的方法&#xff08;静态方法&#xff09;。 单例模式保证了系统内存中该类只存在一个对象&#xf…

C++ 单例模式 代码详解

单例模式 单例模式&#xff08;Singleton Pattern&#xff09;是 最简单的设计模式之一。这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 这种模式涉及到一个单一的类&#xff0c;该类负责创建自己的对象&#xff0c;同时确保只有单个对象被…

[设计模式] -- 单例模式

Emai : hahayacodergmail.com 背景 最近在公司的项目中&#xff0c;经常会用到单例模式&#xff0c;由于之前没有想过怎么正确使用单例模式&#xff0c;导致写成的程序中有BUG。在学习Cocos2d-x时&#xff0c;导演类CCDirector等都是单例类。所以从头开始学习单例模式。 介绍 …

单例模式介绍

目录 1 前言 2 单例模式类型 2.1 饿汉式&#xff1a; 2.2 懒汉式&#xff1a; 2.2.1 双重检查锁 2.2.2 volatile防止指令重排 2.3 静态内部类 3 破坏单例 1 前言 单例模式是指在内存中有且只会创建一次对象的设计模式&#xff0c;在程序中多次使用同一个对象且作用相同…

单例模式详解(附常见的7种单例模式源码)

单例模式&#xff08;Singleton Pattern&#xff09;:保证一个类仅有一个对象&#xff0c;并提供一个访问它的全局访问点。(Ensure a class only has one instance,and provide a globe point of access to it.) 常见应用场景&#xff1a; Windows的Task Manager&#xff08;…

设计模式(一)—单例模式(附Java代码)

单例模式&#xff08;Singleton Pattern&#xff09;:采取一定的方法保证在整个的软件系统中&#xff0c;对于某个类只能存在一个对象实例&#xff0c;并且该类只提供一个取得其实例对象的方法。 比如Hibernate的SessionFactory&#xff0c;它充当数据存储源的代理&#xff0c;…

线程的运行状态

不管是多线程还是多进程&#xff0c;实际上都不太可能一直占用CPU资源&#xff0c;所有多线程的几种状态一定要掌握。 多线程的状态如下图&#xff1a; 所有的系统费资源是有限的&#xff0c;不管是多线程还是多进程都必须在执行一段时间后让出资源&#xff0c;交由其他的线程…

一条SQL语句统计总数及各状态数

需求&#xff1a;共有协议X份&#xff0c;已签XX份&#xff0c;待签X份 sql: select count(1) 总记录数,sum(case when XY_STATUS1 then 1 else 0 end)待签,sum(case when XY_STATUS2 then 1 else 0 end)已签 from YG.T_ZHGL 结果&#xff1a; count(1):所有数据&#xff…

线程的执行状态

1,创建&#xff1a; 当创建好线程对象的时候&#xff0c;也就是new Thread类或者是new Thread子类的时候。此时称为创建状态 2&#xff0c;就绪&#xff1a; 当线程对象调用了start&#xff08;&#xff09;方法&#xff0c;开启线程了的时候&#xff0c;此时的线程已经开启了&…

Java线程线程的状态

1、线程的状态 线程有六种状态&#xff1a;分别如下 ① NEW(新建) 线程刚被创建&#xff0c;但是并未启动。还没调用start方法 ② Runnable(可运行) 线程可以在java虚拟机中运行的状态&#xff0c;可能正在运行自己代码&#xff0c;也可能没有&#xff0c;这取决于操作系统…

Java多线程批量执行sql

当遇到大sql批量导入时几十万上百万数据&#xff0c;使用plsql执行等都是非常的慢。因此开发一套自定义线程池处理sql&#xff1a; 1&#xff0c;线程代码 import java.util.ArrayList;/*** ClassName: com.ai.order.esb.yulang.tools.handle* Description: TODO* version: v1…

一条SQL语句是如何执行的?

大家六一儿童节好呀&#xff01; 接下来的一段时间内&#xff0c;将带领大家一同探索MySQL的奥妙&#xff0c;加油吧&#xff01;我们。 下面进入正题&#xff1a;一条SQL语句是如何进行的&#xff1f; 对于这个问题&#xff0c;我想将其分为两个问题来回答&#xff0c;分别是…