您好,登錄后才能下訂單哦!
1、AtomicLong是利用了底層的CAS操作來提供并發(fā)性。
2、在并發(fā)量較低的環(huán)境下,線程沖突的概率比較小,自旋的次數(shù)不會很多。但是,高并發(fā)環(huán)境下,N個線程同時進行自旋操作,會出現(xiàn)大量失敗并不斷自旋的情況,此時AtomicLong的自旋會成為瓶頸。
3、AtomicLong中有個內(nèi)部volatile變量value保存著實際的long值,所有的操作都是針對該變量進行。也就是說,高并發(fā)環(huán)境下,value變量其實是一個熱點,也就是N個線程競爭一個熱點。
1、LongAdder的基本思路就是分散熱點,將value值分散到一個數(shù)組中,不同線程會命中到數(shù)組的不同槽中,各個線程只對自己槽中的那個值進行CAS操作,這樣熱點就被分散了,沖突的概率就小很多。如果要獲取真正的long值,只要將各個槽中的變量值累加返回。
2、低并發(fā)、一般的業(yè)務場景下AtomicLong是足夠了。如果并發(fā)量很多,存在大量寫多讀少的情況,那LongAdder可能更合適。
1、創(chuàng)建一個Maven工程,Pom.xml代碼如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jane</groupId>
<artifactId>jmh2</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- JMH -->
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.20</version>
</dependency>
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.20</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<id>run-benchmarks</id>
<phase>integration-test</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<classpathScope>test</classpathScope>
<executable>java</executable>
<arguments>
<argument>-classpath</argument>
<classpath />
<argument>org.openjdk.jmh.Main</argument>
<argument>.*</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2、啟動文件
package com.jane;
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
@BenchmarkMode(Mode.AverageTime) // 測試方法平均執(zhí)行時間,如果測試吞入量則換成Mode.Throughput
@OutputTimeUnit(TimeUnit.MICROSECONDS) // 輸出結果的時間粒度為微秒
public class Main {
private static AtomicLong count = new AtomicLong();
private static LongAdder longAdder = new LongAdder();
@Benchmark
@Threads(1) //單位時間內(nèi)也,默認一秒啟動多少個線程進行測試
public void atolong(){
count.getAndIncrement(); //測試AtomicLong遞增方法
}
@Benchmark
@Threads(1) //單位時間內(nèi)也,默認一秒啟動多少個線程進行測試
public void loadder(){
longAdder.increment();//測試LongAdder的遞增方法
}
public static void main(String[] args) throws RunnerException {
Options options = new OptionsBuilder()
.include(Main.class.getSimpleName())
.forks(1)
.build();
new Runner(options).run();
}
}
3、單線程下的性能對比
吞吐量:AtomicLong性能更好
平均消耗時間:AtomicLong耗時更小
4、20個線程下的性能對比
吞吐量:LongAdder優(yōu)勢明顯
平均消耗時間:LongAdder優(yōu)勢明顯
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。