日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java 原子类能做什么_死磕 java原子类之终结篇(面试题)

發(fā)布時間:2025/3/12 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 原子类能做什么_死磕 java原子类之终结篇(面试题) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

概覽

原子操作是指不會被線程調(diào)度機(jī)制打斷的操作,這種操作一旦開始,就一直運(yùn)行到結(jié)束,中間不會有任何線程上下文切換。

原子操作可以是一個步驟,也可以是多個操作步驟,但是其順序不可以被打亂,也不可以被切割而只執(zhí)行其中的一部分,將整個操作視作一個整體是原子性的核心特征。

在java中提供了很多原子類,筆者在此主要把這些原子類分成四大類。

原子更新基本類型或引用類型

如果是基本類型,則替換其值,如果是引用,則替換其引用地址,這些類主要有:

(1)AtomicBoolean

原子更新布爾類型,內(nèi)部使用int類型的value存儲1和0表示true和false,底層也是對int類型的原子操作。

(2)AtomicInteger

原子更新int類型。

(3)AtomicLong

原子更新long類型。

(4)AtomicReference

原子更新引用類型,通過泛型指定要操作的類。

(5)AtomicMarkableReference

原子更新引用類型,內(nèi)部使用Pair承載引用對象及是否被更新過的標(biāo)記,避免了ABA問題。

(6)AtomicStampedReference

原子更新引用類型,內(nèi)部使用Pair承載引用對象及更新的郵戳,避免了ABA問題。

這幾個類的操作基本類似,底層都是調(diào)用Unsafe的compareAndSwapXxx()來實(shí)現(xiàn),基本用法如下:

private static void testAtomicReference() {

AtomicInteger atomicInteger = new AtomicInteger(1);

atomicInteger.incrementAndGet();

atomicInteger.getAndIncrement();

atomicInteger.compareAndSet(3, 666);

System.out.println(atomicInteger.get());

AtomicStampedReference atomicStampedReference = new AtomicStampedReference<>(1, 1);

atomicStampedReference.compareAndSet(1, 2, 1, 3);

atomicStampedReference.compareAndSet(2, 666, 3, 5);

System.out.println(atomicStampedReference.getReference());

System.out.println(atomicStampedReference.getStamp());

}

原子更新數(shù)組中的元素

原子更新數(shù)組中的元素,可以更新數(shù)組中指定索引位置的元素,這些類主要有:

(1)AtomicIntegerArray

原子更新int數(shù)組中的元素。

(2)AtomicLongArray

原子更新long數(shù)組中的元素。

(3)AtomicReferenceArray

原子更新Object數(shù)組中的元素。

這幾個類的操作基本類似,更新元素時都要指定在數(shù)組中的索引位置,基本用法如下:

private static void testAtomicReferenceArray() {

AtomicIntegerArray atomicIntegerArray = new AtomicIntegerArray(10);

atomicIntegerArray.getAndIncrement(0);

atomicIntegerArray.getAndAdd(1, 666);

atomicIntegerArray.incrementAndGet(2);

atomicIntegerArray.addAndGet(3, 666);

atomicIntegerArray.compareAndSet(4, 0, 666);

System.out.println(atomicIntegerArray.get(0));

System.out.println(atomicIntegerArray.get(1));

System.out.println(atomicIntegerArray.get(2));

System.out.println(atomicIntegerArray.get(3));

System.out.println(atomicIntegerArray.get(4));

System.out.println(atomicIntegerArray.get(5));

}

原子更新對象中的字段

原子更新對象中的字段,可以更新對象中指定字段名稱的字段,這些類主要有:

(1)AtomicIntegerFieldUpdater

原子更新對象中的int類型字段。

(2)AtomicLongFieldUpdater

原子更新對象中的long類型字段。

(3)AtomicReferenceFieldUpdater

原子更新對象中的引用類型字段。

這幾個類的操作基本類似,都需要傳入要更新的字段名稱,基本用法如下:

private static void testAtomicReferenceField() {

AtomicReferenceFieldUpdater updateName = AtomicReferenceFieldUpdater.newUpdater(User.class, String.class,"name");

AtomicIntegerFieldUpdater updateAge = AtomicIntegerFieldUpdater.newUpdater(User.class, "age");

User user = new User("tong ge", 21);

updateName.compareAndSet(user, "tong ge", "read source code");

updateAge.compareAndSet(user, 21, 25);

updateAge.incrementAndGet(user);

System.out.println(user);

}

private static class User {

volatile String name;

volatile int age;

public User(String name, int age) {

this.name = name;

this.age = age;

}

@Override

public String toString() {

return "name: " + name + ", age: " + age;

}

}

高性能原子類

高性能原子類,是java8中增加的原子類,它們使用分段的思想,把不同的線程hash到不同的段上去更新,最后再把這些段的值相加得到最終的值,這些類主要有:

(1)Striped64

下面四個類的父類。

(2)LongAccumulator

long類型的聚合器,需要傳入一個long類型的二元操作,可以用來計算各種聚合操作,包括加乘等。

(3)LongAdder

long類型的累加器,LongAccumulator的特例,只能用來計算加法,且從0開始計算。

(4)DoubleAccumulator

double類型的聚合器,需要傳入一個double類型的二元操作,可以用來計算各種聚合操作,包括加乘等。

(5)DoubleAdder

double類型的累加器,DoubleAccumulator的特例,只能用來計算加法,且從0開始計算。

這幾個類的操作基本類似,其中DoubleAccumulator和DoubleAdder底層其實(shí)也是用long來實(shí)現(xiàn)的,基本用法如下:

private static void testNewAtomic() {

LongAdder longAdder = new LongAdder();

longAdder.increment();

longAdder.add(666);

System.out.println(longAdder.sum());

LongAccumulator longAccumulator = new LongAccumulator((left, right)->left + right * 2, 666);

longAccumulator.accumulate(1);

longAccumulator.accumulate(3);

longAccumulator.accumulate(-4);

System.out.println(longAccumulator.get());

}

問題

關(guān)于原子類的問題,筆者整理了大概有以下這些:

(1)Unsafe是什么?

(3)Unsafe為什么是不安全的?

(4)Unsafe的實(shí)例怎么獲取?

(5)Unsafe的CAS操作?

(6)Unsafe的阻塞/喚醒操作?

(7)Unsafe實(shí)例化一個類?

(8)實(shí)例化類的六種方式?

(9)原子操作是什么?

(10)原子操作與數(shù)據(jù)庫ACID中A的關(guān)系?

(11)AtomicInteger怎么實(shí)現(xiàn)原子操作的?

(12)AtomicInteger主要解決了什么問題?

(13)AtomicInteger有哪些缺點(diǎn)?

(14)ABA是什么?

(15)ABA的危害?

(16)ABA的解決方法?

(17)AtomicStampedReference是怎么解決ABA的?

(18)實(shí)際工作中遇到過ABA問題嗎?

(19)CPU的緩存架構(gòu)是怎樣的?

(20)CPU的緩存行是什么?

(21)內(nèi)存屏障又是什么?

(22)偽共享是什么原因?qū)е碌?#xff1f;

(23)怎么避免偽共享?

(24)消除偽共享在java中的應(yīng)用?

(25)LongAdder的實(shí)現(xiàn)方式?

(26)LongAdder是怎么消除偽共享的?

(27)LongAdder與AtomicLong的性能對比?

(28)LongAdder中的cells數(shù)組是無限擴(kuò)容的嗎?

關(guān)于原子類的問題差不多就這么多,都能回答上來嗎?點(diǎn)擊下面的鏈接可以直接到相應(yīng)的章節(jié)查看:

彩蛋

原子類系列源碼分析到此就結(jié)束了,雖然分析的類比較少,但是牽涉的內(nèi)容非常多,特別是操作系統(tǒng)底層的知識,比如CPU指令、CPU緩存架構(gòu)、內(nèi)存屏障等。

下一章,我們將進(jìn)入“同步系列”,同步最常見的就是各種鎖了,這里會著重分析java中的各種鎖、各種同步器以及分布式鎖相關(guān)的內(nèi)容。

歡迎關(guān)注我的公眾號“彤哥讀源碼”,查看更多源碼系列文章, 與彤哥一起暢游源碼的海洋。

總結(jié)

以上是生活随笔為你收集整理的java 原子类能做什么_死磕 java原子类之终结篇(面试题)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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