原子操作类之18罗汉增强AtomicStampedReference、AtomicMarkableReference、LongAdder

文章详细介绍了Java中的原子操作类,包括AtomicInteger、AtomicMarkableReference等,以及它们在并发编程中的应用。通过示例代码展示了如何使用这些原子类进行线程安全的操作,如计数器和属性修改。同时,文章对比了AtomicLong和LongAdder的性能,强调LongAdder在高并发场景下的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


一、是什么




二、再分类

1.基本类型原子类

@Data
@AllArgsConstructor
@NoArgsConstructor
class MyNumber{
    AtomicInteger atomicInteger=new AtomicInteger();
    public void getAndPlus(){
        atomicInteger.getAndIncrement();
    }
}
public class AtomicIntegerDemo {
    public static final int SIZE=50;
    public static void main(String[] args) throws InterruptedException {
        MyNumber myNumber = new MyNumber();
        CountDownLatch countDownLatch=new CountDownLatch(SIZE);
        for (int i = 0; i < SIZE; i++) {
            new Thread(()->{
                try{
                    for (int j = 0; j <1000; j++) {
                        myNumber.getAndPlus();
                    }
                }finally {
                    countDownLatch.countDown();
                }
            },String.valueOf(i)).start();
        }

        //等待上面50个线程全部计算完成后,再去获得最终值
        //try { TimeUnit.SECONDS.sleep(1); }catch (Exception e){e.getMessage();}
        countDownLatch.await();
        System.out.println(Thread.currentThread().getName() +" result "+ myNumber.atomicInteger.get());
    }
}

main result 50000

2.数组类型原子类


3.引用类型原子类

AtomicStampedReference

AtomicMarkableReference

public class AtomicMarkableReferenceDemo {
    static AtomicMarkableReference<Integer> markableReference=new AtomicMarkableReference(100,false);
    public static void main(String[] args) throws InterruptedException {

        new Thread(()->{
            boolean marked = markableReference.isMarked();
            System.out.println(Thread.currentThread().getName()+" 默认标识 "+marked);
            //暂停1秒钟线程,等待后面的t2线程和拿到一样的模式falg标识,都是false
            try { TimeUnit.SECONDS.sleep(1); }catch (Exception e){e.getMessage();}
            markableReference.compareAndSet(100,1000,marked,!marked);

        },"t1").start();

        new Thread(()->{
            boolean marked = markableReference.isMarked();
            System.out.println(Thread.currentThread().getName()+" 默认标识 "+marked);
            //保证t1线程先执行完
            try { TimeUnit.SECONDS.sleep(2); }catch (Exception e){e.getMessage();}
            boolean b = markableReference.compareAndSet(1000, 2000, marked, !marked);
            System.out.println(Thread.currentThread().getName()+" t2线程result "+b);
            System.out.println(Thread.currentThread().getName()+" "+markableReference.isMarked());
            System.out.println(Thread.currentThread().getName()+" "+markableReference.getReference());

        },"t2").start();
    }
}

t1 默认标识 false
t2 默认标识 false
t2 t2线程result false
t2 true
t2 1000

4.对象的属性修改原子类


①:使用目的

②:使用要求

@Data
@AllArgsConstructor
@NoArgsConstructor
class BankAccount{
    //更新的对象属性必须使用public volatile修饰符
    public volatile int totalMoney=0;//账户余额
    String bankName="CCB";

    AtomicIntegerFieldUpdater<BankAccount> fieldUpdater=
            AtomicIntegerFieldUpdater.newUpdater(BankAccount.class,"totalMoney");

    public  void addMoney(int money){
        totalMoney=totalMoney+money;
    }
    //不加synchronized,保证高性能原子性,局部微创小手术
    public void transMoney(BankAccount bankAccount){
        fieldUpdater.getAndIncrement(bankAccount);
    }

}

/**
 * 以一种线程安全的方式操作非线程安全对象的某些字段
 *
 * 需求
 * 100个线程
 * 每个线程转账100
 * 不使用synchronized,尝试使用AtomicIntegerFieldUpdater来实现
 */
public class AtomicIntegerFieldUpdaterDemo {
    public static void main(String[] args) throws InterruptedException {

        BankAccount bankAccount = new BankAccount();
        CountDownLatch countDownLatch=new CountDownLatch(100);
        for (int i = 0; i < 100; i++) {
            new Thread(()->{
                try {
                    for (int j = 0; j < 100; j++) {
                        bankAccount.transMoney(bankAccount);
                    }
                }finally {
                    countDownLatch.countDown();
                }
            },"t1").start();
        }

        countDownLatch.await();
        System.out.println(bankAccount.totalMoney);
    }
}
10000

@Data
@AllArgsConstructor
@NoArgsConstructor
class MyVar{
    public volatile Boolean isInit=false;
    AtomicReferenceFieldUpdater<MyVar,Boolean> fieldUpdater=
            AtomicReferenceFieldUpdater.newUpdater(MyVar.class,Boolean.class,"isInit");

    public void init(MyVar myVar){
        if (fieldUpdater.compareAndSet(myVar,Boolean.FALSE,Boolean.TRUE)){
            System.out.println(Thread.currentThread().getName()+" start init...");
            try { TimeUnit.SECONDS.sleep(2); }catch (Exception e){e.getMessage();}
            System.out.println(Thread.currentThread().getName()+" over init...");
        }else {
            System.out.println(Thread.currentThread().getName()+" 已经有线程在进行初始化工作...");
        }
    }
}

/**
 * 需求
 * 多线程并发调用一个类的初始化方法,如果未被初始化过,将执行初始化工作
 * 要求只能被初始化一次,只要一个线程操作成功
 */
public class AtomicReferenceFieldUpdaterDemo {
    public static void main(String[] args) {
        MyVar myVar=new MyVar();
        for (int i = 1; i <=5; i++) {
            new Thread(()->{
                myVar.init(myVar);
            },String.valueOf(i) ).start();
        }
    }
}
1 start init...
2 已经有线程在进行初始化工作...
3 已经有线程在进行初始化工作...
4 已经有线程在进行初始化工作...
5 已经有线程在进行初始化工作...
1 over init...

5.原子操作增强类原理深度解析



点赞计数器,看看性能



public class LongAdderDemo {
    public static void main(String[] args) {
        //做乘法
        LongAccumulator longAccumulator=new LongAccumulator((x,y)->x*y,2);
        longAccumulator.accumulate(5);
        System.out.println(longAccumulator.get());

        //加法
        LongAccumulator longAccumulator2=new LongAccumulator((x,y)->x+y,2);
        longAccumulator2.accumulate(5);
        System.out.println(longAccumulator2.get());
    }
}

10
7
LongAdder高性能对比code演示
@Data
@AllArgsConstructor
@NoArgsConstructor
class ClickNumber{
    int number=0;
    AtomicLong atomicLong=new AtomicLong(0);
    LongAdder longAdder=new LongAdder();
    LongAccumulator longAccumulator=new LongAccumulator((x,y)->x+y,0);

    public synchronized void clickBySynchronized(){
        number++;
    }

    public void clickByAtomicLong(){
        atomicLong.getAndIncrement();
    }

    public void clickByLongAdder(){
        longAdder.increment();
    }

    public void clickByLongAccumulator(){
        longAccumulator.accumulate(1);
    }

}

/**
 * 需求:50个线程,每个线程100w次,总点赞数出来
 */
public class AccumulatorCompareDemo {
    public static void main(String[] args) throws InterruptedException {
        ClickNumber clickNumber=new ClickNumber();
        CountDownLatch countDownLatch1 =new CountDownLatch(50);
        CountDownLatch countDownLatch2=new CountDownLatch(50);
        CountDownLatch countDownLatch3=new CountDownLatch(50);
        CountDownLatch countDownLatch4=new CountDownLatch(50);
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 50; i++) {
                new Thread(()->{
                    try{
                        for (int j = 0; j < 1000000; j++) {
                            clickNumber.clickBySynchronized();
                        }
                    }finally {
                        countDownLatch1.countDown();
                    }
                }).start();
        }
        countDownLatch1.await();
        long endTime = System.currentTimeMillis();
        System.out.println("clickBySynchronized costTime "+(endTime-startTime) +" result "+clickNumber.number);

        long startTime2 = System.currentTimeMillis();
        for (int i = 0; i < 50; i++) {
            new Thread(()->{
                try{
                    for (int j = 0; j < 1000000; j++) {
                        clickNumber.clickByAtomicLong();
                    }
                }finally {
                    countDownLatch2.countDown();
                }
            }).start();
        }
        countDownLatch2.await();
        long endTime2 = System.currentTimeMillis();
        System.out.println("clickByAtomicLong costTime "+(endTime2-startTime2) +" result "+clickNumber.number);

        long startTime3 = System.currentTimeMillis();
        for (int i = 0; i < 50; i++) {
            new Thread(()->{
                try{
                    for (int j = 0; j < 1000000; j++) {
                        clickNumber.clickByLongAdder();
                    }
                }finally {
                    countDownLatch3.countDown();
                }
            }).start();
        }
        countDownLatch3.await();
        long endTime3 = System.currentTimeMillis();
        System.out.println("clickByLongAdder costTime "+(endTime3-startTime3) +" result "+clickNumber.number);

        long startTime4 = System.currentTimeMillis();
        for (int i = 0; i < 50; i++) {
            new Thread(()->{
                try{
                    for (int j = 0; j < 1000000; j++) {
                        clickNumber.clickByLongAccumulator();
                    }
                }finally {
                    countDownLatch4.countDown();
                }
            }).start();
        }
        countDownLatch4.await();
        long endTime4 = System.currentTimeMillis();
        System.out.println("clickByLongAccumulator costTime "+(endTime4-startTime4) +" result "+clickNumber.number);
    }
}

clickBySynchronized costTime 1820 result 50000000
clickByAtomicLong costTime 951 result 50000000
clickByLongAdder costTime 153 result 50000000
clickByLongAccumulator costTime 166 result 50000000

源码、原理分析






LongAdder为什么这么快







在这里插入图片描述




AtomicLong与LongAdder比较




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值