首页 > 其他分享 >使用AtomicInteger原子类尝试优化分析

使用AtomicInteger原子类尝试优化分析

时间:2024-09-08 23:23:24浏览次数:11  
标签:尝试 LongAdder Thread System AtomicInteger 原子 threads new

1. 使用AtomicInteger原子类尝试优化分析

Java的java.util.concurrent.atomic包提供了一些原子类,可以在并发编程中避免显式加锁。最简单的我们可以使用AtomicInteger来替代显式的锁。


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

import java.util.concurrent.atomic.AtomicInteger;

/**

* @program: zyfboot-javabasic

* @description: 使用AtomicInteger来替代显式的锁

* @author: zhangyanfeng

* @create: 2024-06-05 23:07

**/

public class AtomicExample {

   private static AtomicInteger counter = new AtomicInteger(0);

   public static void main(String[] args) throws InterruptedException {

       long startTime = System.currentTimeMillis();

       Thread[] threads = new Thread[100];

       for (int i = 0; i < 100; i++) {

           threads[i] = new Thread(new IncrementAtomic());

           threads[i].start();

       }

       for (Thread thread : threads) {

           thread.join();

       }

       long endTime = System.currentTimeMillis();

       System.out.println("Time with AtomicInteger: " + (endTime - startTime) + " ms");

   }

   static class IncrementAtomic implements Runnable {

       @Override

       public void run() {

           for (int i = 0; i < 1000000; i++) {

               counter.incrementAndGet();

           }

       }

   }

}

理论上这样优化后性能上必会上升,但实际上运行后其耗时为 6714 ms,性能反而变差了。这里其实我们之前的博客中也有讲过,其主要的原因有两个:


原子类的开销:AtomicInteger的incrementAndGet方法虽然是无锁的,但它依赖于底层的CAS(Compare-And-Swap)操作。CAS操作虽然是无锁的,但在高并发情况下,多个线程同时尝试更新同一个变量时,CAS操作可能会频繁地失败并重试,从而导致性能下降。相比之下,ReentrantLock在某些情况下可能反而表现更好,尤其是在锁争用不是特别激烈的时候。

高并发下的内存争用:在高并发情况下,多个线程同时访问和修改共享变量会导致内存争用。这种争用在使用AtomicInteger时表现得更为明显,因为每次操作都需要与主内存同步,可能会导致缓存一致性协议的开销。

2. 对AtomicInteger原子类进一步优化

我们可以尝试以下方法来进一步优化:


减少线程数量:在本示例中,我们使用了100个线程同时访问共享变量,这可能导致过多的上下文切换和争用。可以尝试减少线程数量,看看性能是否有所改善。

使用更高效的同步机制:可以尝试使用其他同步机制,如LongAdder或ConcurrentLinkedQueue等,这些工具在高并发场景下通常表现更好。

这里我们直接用LongAdder验证,具体代码如下:


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

import java.util.concurrent.atomic.LongAdder;

/**

* @program: zyfboot-javabasic

* @description: LongAdder在高并发情况下比AtomicInteger有更好的性能

* @author: zhangyanfeng

* @create: 2024-06-05 23:26

**/

public class LongAdderExample {

   private static LongAdder counter = new LongAdder();

   public static void main(String[] args) throws InterruptedException {

       long startTime = System.currentTimeMillis();

       Thread[] threads = new Thread[100];

       for (int i = 0; i < 100; i++) {

           threads[i] = new Thread(new IncrementLongAdder());

           threads[i].start();

       }

       for (Thread thread : threads) {

           thread.join();

       }

       long endTime = System.currentTimeMillis();

       System.out.println("Time with LongAdder: " + (endTime - startTime) + " ms");

   }

   static class IncrementLongAdder implements Runnable {

       @Override

       public void run() {

           for (int i = 0; i < 1000000; i++) {

               counter.increment();

           }

       }

   }

}

运行后发现这个时候的耗时基本在204 ms,优化还是很明显的。


标签:尝试,LongAdder,Thread,System,AtomicInteger,原子,threads,new
From: https://blog.51cto.com/u_16271212/11953431

相关文章

  • 小白建立个人网站初步尝试
    一、VScode 代码是在VScode上运行的,可以看作者另一篇文章:http://t.csdnimg.cn/mOmdF二、代码基本框架代码解释<!DOCTYPEhtml>声明为HTML5文档<html><head>头部元素,不显示在页面<metacharset="utf-8">防止页面中的中文出现乱码<title>...</title>网站的标题</head>与<head......
  • CAS与原子操作
    什么是原子操作?原子操作是一种在执行过程中不会被中断的操作。它要么完全执行成功,要么完全不执行,确保在操作完成之前其他线程不会看到操作的中间状态。原子操作的实现CASCAS是由CPU提供的原子指令。在硬件级别上确保操作的原子性。不涉及上下文切换,性能高主要用途:单......
  • 【正点原子K210连载】第二十九章 音频录制实验 摘自【正点原子】DNK210使用指南-CanMV
    第二十九章音频录制实验本章将介绍CanMV下的音频录制通过CanMV提供的模块便能快速地实现音频录制。通过本章的学习,读者将学习到CanMV下控制I2S获取音频数和audio模块的使用。本章分为如下几个小节:29.1maix.I2S模块及audio模块介绍29.2硬件设计29.3程序设计29.4运行验证29......
  • 【正点原子K210连载】第三十章 照片拍摄实验 摘自【正点原子】DNK210使用指南-CanMV版
    第三十章照片拍摄实验在前面的章节中,已经了解了如何在CanMV下获取摄像头输出的图像数据并在LCD上进行显示,同时也了解了如何解码文件系统中的图像文件然后在LCD上进行显示,本章将通过照片拍摄实验,介绍如何通过CanMV将摄像头输出的图像数据进行图像编码保存到文件系统中。通过本章的......
  • 【正点原子K210连载】第二十四章 LCD显示实验 摘自【正点原子】DNK210使用指南-CanMV
    第二十四章LCD显示实验本章将介绍初步介绍CanMV下LCD的使用。通过本章的学习,读者将学习到板载LCD的简单使用。本章分为如下几个小节:24.1lcd模块介绍24.2硬件设计24.3程序设计24.4运行验证24.1lcd模块介绍lcd模块是CanMV内置的模块,lcd模块用于驱动LCD进行一些简单的显示......
  • 【正点原子K210连载】第二十五章 LCD图片显示实验 摘自【正点原子】DNK210使用指南-Ca
    第二十五章LCD图片显示实验本章将介绍在LCD上的图片显示。通过本章的学习,读者将学习到LCD上图片的显示。本章分为如下几个小节:25.1lcd模块介绍25.2硬件设计25.3程序设计25.4运行验证25.1lcd模块介绍有关lcd模块的介绍,请见第24.1小节《lcd模块介绍》。25.2硬件设计25......
  • C++ 原子变量atomic variable
    原子变量原子变量(atomicvariable)是C++11引入的一种同步机制,用于在多线程环境中进行无锁的、线程安全的操作。原子变量的操作是不可分割的,即在执行过程中不会被其他线程中断,从而避免了数据竞争和不一致的问题。原子变量位于头文件中。基本概念原子性原子性:一个操作是......
  • 使用centos7搭建Cloudreve,在这条路上我尝试过自建、Owncloud等,恰巧最近发现了 Cloudre
     1.首先开始之前配置一个华为的源vi/etc/yum.repos.d/openstack.repo#内容如下[base]name=basebaseurl=https://repo.huaweicloud.com/centos/7/os/x86_64/enable=1gpgcheck=0[extras]name=extraxbaseurl=https://repo.huaweicloud.com/centos/7/extras/x86_64/......
  • 正点原子FPGA新品ZYNQ7035/7045/7100开发板,ZYNQ 7000系列、双核ARM、PCIe2.0、SFPX2!
    正点原子FPGA新品ZYNQ7035/7045/7100开发板,ZYNQ7000系列、双核ARM、PCIe2.0、SFPX2!正点原子Z100ZYNQ开发板,搭载XilinxZynq7000系列芯片,核心板支持XilinxZynq-7035、Zynq-7045和Zynq-7100三种型号。开发板由核心板+底板组成,外设资源丰富,板载2路千兆以太网接口(PS+PL)、PCIe2.0x8、......
  • 【新品8折】正点原子ZYNQ7035/7045/7100开发板发布、ZYNQ 7000系列、双核ARM、PCIe2.0
    【新品发布】正点原子FPGA新品ZYNQ7035/7045/7100开发板,ZYNQ7000系列、双核ARM、PCIe2.0、SFPX2!正点原子Z100ZYNQ开发板,搭载XilinxZynq7000系列芯片,核心板支持XilinxZynq-7035、Zynq-7045和Zynq-7100三种型号。开发板由核心板+底板组成,外设资源丰富,板载2路千兆以太网接口(PS+P......