JUC-AtomicxxxFieldUpdater

AtomicIntegerFieldUpdater:原子更新对象中int字段的值

AtomicLongFieldUpdater:原子更新对象中long字段的值

AtomicReferenceFieldUpdater:原子更新引用类型字段的值

目的:以一种线程安全的方式操作非线程安全对象内的某些字段

使用要求:1、更新的对象属性必须使用public volatile修饰

                  2、 必须使用静态方法newUpdater()创建一个更新器,设置需要更新的类和属性

AtomicIntegerFieldUpdater示例

package com.example.juc.controller;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;

/**
 * @author jl
 * @since 2021/10/10 13:17
 */
class BankAccount {
    private String name = "ccb";
    public volatile int money;
    AtomicIntegerFieldUpdater fieldUpdater = AtomicIntegerFieldUpdater.newUpdater(BankAccount.class, "money");

    BankAccount() {
    }

    public void transfer(BankAccount bankAccount) {
        fieldUpdater.incrementAndGet(bankAccount);
    }
    public AtomicInteger balance = new AtomicInteger(0);
}
public class AtomicIntegerFieldUpdaterDemo {
    public static void main(String[] args) throws InterruptedException {
        BankAccount bankAccount = new BankAccount();
        int count = 100;
        CountDownLatch countDownLatch = new CountDownLatch(count);
        for (int i = 0; i < count; i++) {
            new Thread(()->{
                try {
                    bankAccount.transfer(bankAccount);
                    bankAccount.balance.incrementAndGet();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    countDownLatch.countDown();
                }
            }).start();
        }
        countDownLatch.await();
        System.out.println("bankAccount.money = " + bankAccount.money);
        System.out.println("bankAccount.balance.get() = " + bankAccount.balance.get());
    }
}

 bankAccount.money = 100
bankAccount.balance.get() = 100

AtomicReferenceFieldUpdater示例

class MyVar {
    public volatile Boolean isInit = Boolean.FALSE;
    AtomicReferenceFieldUpdater 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(3); } catch (InterruptedException e) { e.printStackTrace(); };
            System.out.println(Thread.currentThread().getName() + " --- end 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);
            }, i + "").start();
        }
    }
}

 1 --- start init
2 --- 竞争失败,已经有线程在修正中
4 --- 竞争失败,已经有线程在修正中
3 --- 竞争失败,已经有线程在修正中
1 --- end init

上一篇:JUC多线程:AQS抽象队列同步器原理


下一篇:JUC之文章整理以及汇总