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