本篇内容主要讲解“怎么实现Java JDK没有提供的AtomicFloat”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么实现Java JDK没有提供的AtomicFloat”吧!
我们经常会使用AtomicInteger来做计数器,如下所示:
List<String> words = Files.readAllLines(Paths.get("src/main/resources/dic.txt")); AtomicInteger i = new AtomicInteger(); words.parallelStream().forEach(word -> { //获取word的同义词、反义词以及相关词 //...... LOGGER.info("进度:" + total + "/" + i.incrementAndGet() + " 来自线程:" + Thread.currentThread()); });
在这段代码中,我们需要注意两点,一是parallelStream,二是变量i。
parallelStream的使用表示forEach中的代码段有可能会在不同线程中并发执行,因此变量i的incrementAndGet方法要保证是原子操作,否则计数器的数据就可能会出错。
没啥问题,一切都还很美好,so far so nice。
有一天,我们的需求复杂了,我们需要的计数器不仅仅只是+1,而是要支持小数,如2.5,3.1等等,这有什么大不了的,我们把AtomicInteger换成AtomicFloat不就支持小数了吗?
接着我们翻遍了JDK类库,都没有找到AtomicFloat,怎么回事呢?
最后终于在java.util.concurrent.atomic的package-summary.html页面的最后部分发现了秘密:
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.
接下来我们就可以利用AtomicInteger作为基础来实现自己的AtomicFloat了,实现AtomicDouble和AtomicByte也是类似的做法,下面看看在word分词中实现的AtomicFloat:
package org.apdplat.word.util; import java.util.concurrent.atomic.AtomicInteger; /** * 因为Java没有提供AtomicFloat * 所以自己实现一个 * @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()); } }
到此,相信大家对“怎么实现Java JDK没有提供的AtomicFloat”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。