小編給大家分享一下java原子類面試題有哪些,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、小程序制作、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了吳中免費(fèi)建站歡迎大家使用!原子操作是指不會(huì)被線程調(diào)度機(jī)制打斷的操作,這種操作一旦開始,就一直運(yùn)行到結(jié)束,中間不會(huì)有任何線程上下文切換。
原子操作可以是一個(gè)步驟,也可以是多個(gè)操作步驟,但是其順序不可以被打亂,也不可以被切割而只執(zhí)行其中的一部分,將整個(gè)操作視作一個(gè)整體是原子性的核心特征。
在java中提供了很多原子類,筆者在此主要把這些原子類分成四大類。
如果是基本類型,則替換其值,如果是引用,則替換其引用地址,這些類主要有:
(1)AtomicBoolean
原子更新布爾類型,內(nèi)部使用int類型的value存儲(chǔ)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問題。
這幾個(gè)類的操作基本類似,底層都是調(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()); AtomicStampedReferenceatomicStampedReference = 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ù)組中指定索引位置的元素,這些類主要有:
(1)AtomicIntegerArray
原子更新int數(shù)組中的元素。
(2)AtomicLongArray
原子更新long數(shù)組中的元素。
(3)AtomicReferenceArray
原子更新Object數(shù)組中的元素。
這幾個(gè)類的操作基本類似,更新元素時(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
原子更新對象中的引用類型字段。
這幾個(gè)類的操作基本類似,都需要傳入要更新的字段名稱,基本用法如下:
private static void testAtomicReferenceField() { AtomicReferenceFieldUpdaterupdateName = 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
下面四個(gè)類的父類。
(2)LongAccumulator
long類型的聚合器,需要傳入一個(gè)long類型的二元操作,可以用來計(jì)算各種聚合操作,包括加乘等。
(3)LongAdder
long類型的累加器,LongAccumulator的特例,只能用來計(jì)算加法,且從0開始計(jì)算。
(4)DoubleAccumulator
double類型的聚合器,需要傳入一個(gè)double類型的二元操作,可以用來計(jì)算各種聚合操作,包括加乘等。
(5)DoubleAdder
double類型的累加器,DoubleAccumulator的特例,只能用來計(jì)算加法,且從0開始計(jì)算。
這幾個(gè)類的操作基本類似,其中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í)例化一個(gè)類?
(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ū)е碌模?/p>
(23)怎么避免偽共享?
(24)消除偽共享在java中的應(yīng)用?
(25)LongAdder的實(shí)現(xiàn)方式?
(26)LongAdder是怎么消除偽共享的?
(27)LongAdder與AtomicLong的性能對比?
(28)LongAdder中的cells數(shù)組是無限擴(kuò)容的嗎?
以上是“java原子類面試題有哪些”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)網(wǎng)站制作公司行業(yè)資訊頻道!
創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開啟,新人活動(dòng)云服務(wù)器買多久送多久。