您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“怎么實(shí)現(xiàn)Java JDK沒(méi)有提供的AtomicFloat”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“怎么實(shí)現(xiàn)Java JDK沒(méi)有提供的AtomicFloat”吧!
我們經(jīng)常會(huì)使用AtomicInteger來(lái)做計(jì)數(shù)器,如下所示:
List<String> words = Files.readAllLines(Paths.get("src/main/resources/dic.txt")); AtomicInteger i = new AtomicInteger(); words.parallelStream().forEach(word -> { //獲取word的同義詞、反義詞以及相關(guān)詞 //...... LOGGER.info("進(jìn)度:" + total + "/" + i.incrementAndGet() + " 來(lái)自線程:" + Thread.currentThread()); });
在這段代碼中,我們需要注意兩點(diǎn),一是parallelStream,二是變量i。
parallelStream的使用表示forEach中的代碼段有可能會(huì)在不同線程中并發(fā)執(zhí)行,因此變量i的incrementAndGet方法要保證是原子操作,否則計(jì)數(shù)器的數(shù)據(jù)就可能會(huì)出錯(cuò)。
沒(méi)啥問(wèn)題,一切都還很美好,so far so nice。
有一天,我們的需求復(fù)雜了,我們需要的計(jì)數(shù)器不僅僅只是+1,而是要支持小數(shù),如2.5,3.1等等,這有什么大不了的,我們把AtomicInteger換成AtomicFloat不就支持小數(shù)了嗎?
接著我們翻遍了JDK類庫(kù),都沒(méi)有找到AtomicFloat,怎么回事呢?
最后終于在java.util.concurrent.atomic的package-summary.html頁(yè)面的最后部分發(fā)現(xiàn)了秘密:
Additionally, classes are provided only for those types that are commonly useful in intended applications. For example, there is no atomic class for representing byte
. In those infrequent cases where you would like to do so, you can use an AtomicInteger
to hold byte
values, and cast appropriately. You can also hold floats using Float.floatToRawIntBits(float)
andFloat.intBitsToFloat(int)
conversions, and doubles using Double.doubleToRawLongBits(double)
andDouble.longBitsToDouble(long)
conversions.
接下來(lái)我們就可以利用AtomicInteger作為基礎(chǔ)來(lái)實(shí)現(xiàn)自己的AtomicFloat了,實(shí)現(xiàn)AtomicDouble和AtomicByte也是類似的做法,下面看看在word分詞中實(shí)現(xiàn)的AtomicFloat:
package org.apdplat.word.util; import java.util.concurrent.atomic.AtomicInteger; /** * 因?yàn)镴ava沒(méi)有提供AtomicFloat * 所以自己實(shí)現(xiàn)一個(gè) * @author 楊尚川 */ public class AtomicFloat extends Number { private AtomicInteger bits; public AtomicFloat() { this(0f); } public AtomicFloat(float initialValue) { bits = new AtomicInteger(Float.floatToIntBits(initialValue)); } public final float addAndGet(float delta){ float expect; float update; do { expect = get(); update = expect + delta; } while(!this.compareAndSet(expect, update)); return update; } public final float getAndAdd(float delta){ float expect; float update; do { expect = get(); update = expect + delta; } while(!this.compareAndSet(expect, update)); return expect; } public final float getAndDecrement(){ return getAndAdd(-1); } public final float decrementAndGet(){ return addAndGet(-1); } public final float getAndIncrement(){ return getAndAdd(1); } public final float incrementAndGet(){ return addAndGet(1); } public final float getAndSet(float newValue) { float expect; do { expect = get(); } while(!this.compareAndSet(expect, newValue)); return expect; } public final boolean compareAndSet(float expect, float update) { return bits.compareAndSet(Float.floatToIntBits(expect), Float.floatToIntBits(update)); } public final void set(float newValue) { bits.set(Float.floatToIntBits(newValue)); } public final float get() { return Float.intBitsToFloat(bits.get()); } public float floatValue() { return get(); } public double doubleValue() { return (double) floatValue(); } public int intValue() { return (int) get(); } public long longValue() { return (long) get(); } public String toString() { return Float.toString(get()); } }
到此,相信大家對(duì)“怎么實(shí)現(xiàn)Java JDK沒(méi)有提供的AtomicFloat”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。