JUC, java.util.concurrent并发工具包下。
1.原子整数
AtomicInteger
AtomicLong
AtomicBoolean
底层用的CAS来实现。
AtomicInteger类的incrementAndGet方法,addAndGet方法
java
public static void main(String[] args) {
AtomicInteger atomicInteger = new AtomicInteger();
int i = atomicInteger.incrementAndGet(); //i++
log.info("i=={}", i);
//这里返回的是1,但是atomicInteger中的值已经变成2了
int j = atomicInteger.getAndIncrement();//++i
log.info("j=={}", j);
log.info("value=={}", atomicInteger.get());
//先返回原来的值
int andAdd = atomicInteger.getAndAdd(2);
log.info("andAdd={}", andAdd);
//返回加运算之后的值
int i1 = atomicInteger.addAndGet(3);
log.info("i1=={}", i1);
}
int andAdd = atomicInteger.getAndAdd(-1 * 2); //减法
AtomicInteger类的updateAndGet方法的原理分析:
public final int updateAndGet(IntUnaryOperator updateFunction) { int prev, next; do { prev = get(); next = updateFunction.applyAsInt(prev); } while (!compareAndSet(prev, next)); return next; }
IntUnaryOperator这个接口中定义了方法 int applyAsInt(int prev),所以调用者只需要传入applyAsInt方法的实现逻辑即可。
AtomicInteger atomicInteger = new AtomicInteger(5); //**乘法 int i2 = atomicInteger.updateAndGet(e -> e * 10); log.info("i2=={}", i2);
2.原子引用类型
AtomicReference
AtomicMarkableReference
AtomicStampedReference
java
public class AccountDemo {
public static void main(String[] args) {
BigdecimalAccountCAS bigdecimalAccountCAS = new BigdecimalAccountCAS(new BigDecimal("10000"));
BigDecimalAccount.demo(bigdecimalAccountCAS);
}
}
class BigdecimalAccountCAS implements BigDecimalAccount{
private AtomicReference<BigDecimal> balance;
public BigdecimalAccountCAS (BigDecimal balance) {
this.balance = new AtomicReference<>(balance);
}
@Override
public BigDecimal getBalance() {
return this.balance.get();
}
@Override
public void withDraw(BigDecimal amont) {
while(true) {
BigDecimal prev = balance.get();
BigDecimal subtract = prev.subtract(amont);
if (balance.compareAndSet(prev, subtract)) {
break;
}
}
// this.balance.updateAndGet(e -> e.subtract(amont));
}
}
interface BigDecimalAccount {
//获取余额
BigDecimal getBalance();
//取款
void withDraw(BigDecimal amont);
static void demo(BigDecimalAccount account) {
//定义一个线程集合
List<Thread> ts = new ArrayList<>();
long start = System.nanoTime();
//创建一千个线程,每个线程取出10元
for (int i = 0; i < 1000; i++) {
ts.add(new Thread(() -> account.withDraw(BigDecimal.TEN)));
}
//启动每一个线程
ts.forEach( e -> e.start());
//等所有线程执行完毕
ts.forEach( e -> {
try {
e.join();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
});
long duration = System.nanoTime() - start;
System.out.println("花费时长:"+duration);
System.out.println("余额:"+ account.getBalance());
}
}