Java --Atomic(原子)

原子性操作,在多线程下 该变量的操作是原子性的,不需要添加:synchronized

例子

启用100个线程,每个线程做+1的操作,最终的结果应该会得到 100才对

public static void main(String args[]) throws InterruptedException {
        //使用线程池
        ExecutorService service = Executors.newCachedThreadPool();
        TestCount testCount=new TestCount();
        long time=System.currentTimeMillis();
        //100个线程对count+1
        for(int i=1;i<=100;i++){
           service.execute(()->testCount.increase());
        }
        // 等待上述的线程执行完
        service.shutdown();
        service.awaitTermination(1, TimeUnit.DAYS);
        System.out.println("计算结果:"+testCount.getCount());
    }
    
     //类
    public static final class TestCount{
        private Integer count=0;

        public Integer getCount() {
            return count;
        }

        public void setCount(Integer count) {
            this.count = count;
        }
        
        public void increase(){
            count++;
        }
    }

最终的记结果会出现 97 96 .等的情况,就是说count 这个共享变量是线程不安全的呀,线程都共享这个变量


image.png

使用 AtomicInteger 修改count 变量

    public static final class TestCount{
        private AtomicInteger count = new AtomicInteger(0);
        public Integer getCount() {
            return count.get();
        }
        public void increase(){
            count.incrementAndGet();
        }
    }

不管执行多少次都是100 结果正确


image.png

Atomic 的类

image.png

基本类型:
AtomicBoolean:布尔型
AtomicInteger:整型
AtomicLong:长整型

数组:
AtomicIntegerArray:数组里的整型
AtomicLongArray:数组里的长整型
AtomicReferenceArray:数组里的引用类型

引用类型:
AtomicReference:引用类型
AtomicStampedReference:带有版本号的引用类型
AtomicMarkableReference:带有标记位的引用类型

对象的属性:
AtomicIntegerFieldUpdater:对象的属性是整型
AtomicLongFieldUpdater:对象的属性是长整型
AtomicReferenceFieldUpdater:对象的属性是引用类型
JDK8新增DoubleAccumulator、LongAccumulator、DoubleAdder、LongAdder
是对AtomicLong等类的改进。比如LongAccumulator与LongAdder在高并发环境下比AtomicLong更高效。

AtomicReferenceFieldUpdater、AtomicIntegerFieldUpdater和AtomicLongFieldUpdater是基于反射的实用工具,可以提供对关联字段类型的访问。例如AtomicIntegerFieldUpdater可以对指定类的指定volatile int字段进行原子更新。

原子类可以替换锁吗?
原子类不是锁的常规替换方法。仅当对象的重要更新限定于单个变量时才应用它。

原子类和java.lang.Integer等类的区别
原子类不提供诸如hashCode和compareTo之类的方法。因为原子变量是可变的。

:LongAdder中会维护一组(一个或多个)变量,这些变量加起来就是要以原子方式更新的long型变量。当更新方法add(long)在线程间竞争时,该组变量可以动态增长以减缓竞争。方法sum()返回当前在维持总和的变量上的总和。与AtomicLong相比,LongAdder更多地用于收集统计数据,而不是细粒度的同步控制。在低并发环境下,两者性能很相似。但在高并发环境下,LongAdder有着明显更高的吞吐量,但是有着更高的空间复杂度。

import java.util.concurrent.atomic.AtomicLong;

class Counter {
    private static AtomicLong counter = new AtomicLong(0);

    public static long addOne() {
        return counter.incrementAndGet();
    }
}
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 什么是原子类 原子是不可分割的最小单位,故原子类可以认为其操作都是不可分割 一个操作时不可中断的,即便是在多线程的...
    小波同学阅读 915评论 0赞 1
  • 前言 只有光头才能变强 之前已经写过多线程相关的文章了,有兴趣的同学可以去了解一下: https://github...
    Java3y阅读 1,701评论 1赞 24
  • java atomic 原子变量提供各种原子操作,多线程场景下操作不需要加锁,性能非常好 简例 AtomicInt...
    hatlonely阅读 584评论 0赞 0
  • 线程安全性 线程安全性定义: 当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些进程将如何交替执行,并...
    端碗吹水阅读 199评论 0赞 0
  • 第一种(不推荐,功力不够,用错会达不到同步效果)synchronized正确用法 第二种 第三种(优先选择) 参考...
    else05阅读 9,554评论 0赞 2

友情链接更多精彩内容