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();
    }
}

你可能感兴趣的:(Java --Atomic(原子))