日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

[JDK8]性能优化之使用LongAdder替换AtomicLong

發(fā)布時間:2025/7/14 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [JDK8]性能优化之使用LongAdder替换AtomicLong 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

如果讓你實現(xiàn)一個計數(shù)器,有點經(jīng)驗的同學(xué)可以很快的想到使用AtomicInteger或者AtomicLong進(jìn)行簡單的封裝。

因為計數(shù)器操作涉及到內(nèi)存的可見性和線程之間的競爭,而Atomic***的實現(xiàn)完美的屏蔽了這些技術(shù)細(xì)節(jié),我們只需要執(zhí)行相應(yīng)的方法,就能實現(xiàn)對應(yīng)的業(yè)務(wù)需求。

Atomic**雖然好用,不過這些的操作在并發(fā)量很大的情況下,性能問題也會被相應(yīng)的放大。我們可以先看下其中getAndIncrement的實現(xiàn)代碼

public final long getAndIncrement() {return unsafe.getAndAddLong(this, valueOffset, 1L); }// unsafe類中的實現(xiàn) public final long getAndAddLong(Object var1, long var2, long var4) {long var6;do {var6 = this.getLongVolatile(var1, var2);} while(!this.compareAndSwapLong(var1, var2, var6, var6 + var4));return var6; }

很顯然,在getAndAddLong實現(xiàn)中,為了實現(xiàn)正確的累加操作,如果并發(fā)量很大的話,cpu會花費大量的時間在試錯上面,相當(dāng)于一個spin(自旋)的操作。如果并發(fā)量小的情況,這些消耗可以忽略不計。

既然已經(jīng)意識到Atomic***有這樣的業(yè)務(wù)缺陷,Doug Lea大神又給我們提供了LongAdder,內(nèi)部的實現(xiàn)有點類似ConcurrentHashMap的分段鎖,最好的情況下,每個線程都有獨立的計數(shù)器,這樣可以大量減少并發(fā)操作。

下面通過JMH比較一下AtomicLong 和 LongAdder的性能。

@OutputTimeUnit(TimeUnit.MICROSECONDS) @BenchmarkMode(Mode.Throughput) public class Main {private static AtomicLong count = new AtomicLong();private static LongAdder longAdder = new LongAdder();public static void main(String[] args) throws Exception {Options options = new OptionsBuilder().include(Main.class.getName()).forks(1).build();new Runner(options).run();}@Benchmark@Threads(10)public void run0(){count.getAndIncrement();}@Benchmark@Threads(10)public void run1(){longAdder.increment();} }

1、設(shè)置BenchmarkMode為Mode.Throughput,測試吞吐量
2、設(shè)置BenchmarkMode為Mode.AverageTime,測試平均耗時

?

線程數(shù)為1

1、吞吐量

Benchmark Mode Cnt Score Error Units Main.run0 thrpt 5 154.525 ± 9.767 ops/us Main.run1 thrpt 5 89.599 ± 7.951 ops/us

2、平均耗時

Benchmark Mode Cnt Score Error Units Main.run0 avgt 5 0.007 ± 0.001 us/op Main.run1 avgt 5 0.011 ± 0.001 us/op

單線程情況:
1、AtomicLong的吞吐量和平均耗時都占優(yōu)勢

?

線程數(shù)為10

1、吞吐量

Benchmark Mode Cnt Score Error Units Main.run0 thrpt 5 37.780 ± 1.891 ops/us Main.run1 thrpt 5 464.927 ± 143.207 ops/us

2、平均耗時

Benchmark Mode Cnt Score Error Units Main.run0 avgt 5 0.290 ± 0.038 us/op Main.run1 avgt 5 0.021 ± 0.001 us/op

并發(fā)線程為10個時:

  • LongAdder的吞吐量比較大,是AtomicLong的10倍多。
  • LongAdder的平均耗時是AtomicLong的十分之一。

?

線程數(shù)為30

1、吞吐量 Benchmark Mode Cnt Score Error Units Main.run0 thrpt 5 36.215 ± 2.341 ops/us Main.run1 thrpt 5 486.630 ± 26.894 ops/us

2、平均耗時

Benchmark Mode Cnt Score Error Units Main.run0 avgt 5 0.792 ± 0.021 us/op Main.run1 avgt 5 0.063 ± 0.002 us/op

線程數(shù)為30個時:

  • LongAdder的吞吐量比較大,也是AtomicLong的10倍多。
  • LongAdder的平均耗時也是AtomicLong的十分之一。

總結(jié)

一些高并發(fā)的場景,比如限流計數(shù)器,建議使用LongAdder替換AtomicLong,性能可以提升不少。

轉(zhuǎn)載于:https://www.cnblogs.com/Joy-Hu/p/10715682.html

《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的[JDK8]性能优化之使用LongAdder替换AtomicLong的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。