CAS是什么

首先CAS是基于无锁的乐观锁思想实现,保证其原子操作。

CAS实现类

引用类型原子类:

  • AtomicReference(引用类型原子类)
  • AtomicStampedRerence(携带版本号,可以解决CAS中ABA问题)
  • AtomicMarkableReference(原子更新带有标记位的引用类型)

基础原子类:

  • AtomicBoolean
  • AtomicInteger
  • AtomicLong

原子数组类:

  • AtomicLongArray
  • AtomicReferenceArray

原子方式更新对象中的字段类:

  • AtomicIntegerFieldUpdate
  • AtomicReferenceFieldUpdate

高并发汇总类:

  • LongAdder
  • LongAccumulator
  • DoubleAdder
  • DoubleAccumulator

    synchronized加锁实例

    ```java public class TestAccount { public static void main(String[] args) {
    1. Account account = new AccountUnsafe(10000);
    2. Account.demo(account);
    } }

class AccountUnsafe implements Account {

  1. private Integer balance;
  2. public AccountUnsafe(Integer balance) {
  3. this.balance = balance;
  4. }
  5. @Override
  6. public Integer getBalance() {
  7. synchronized (this) {
  8. return this.balance;
  9. }
  10. }
  11. @Override
  12. public void withdraw(Integer amount) {
  13. synchronized (this) {
  14. this.balance -= amount;
  15. }
  16. }

}

interface Account { // 获取余额 Integer getBalance();

  1. // 取款
  2. void withdraw(Integer amount);
  3. /**
  4. * 方法内会启动 1000 个线程,每个线程做 -10 元 的操作
  5. * 如果初始余额为 10000 那么正确的结果应当是 0
  6. */
  7. static void demo(Account account) {
  8. List<Thread> ts = new ArrayList<>();
  9. for (int i = 0; i < 1000; i++) {
  10. ts.add(new Thread(() -> {
  11. account.withdraw(10);
  12. }));
  13. }
  14. long start = System.nanoTime();
  15. ts.forEach(Thread::start);
  16. ts.forEach(t -> {
  17. try {
  18. t.join();
  19. } catch (InterruptedException e) {
  20. e.printStackTrace();
  21. }
  22. });
  23. long end = System.nanoTime();
  24. System.out.println(account.getBalance()
  25. + " cost: " + (end-start)/1000_000 + " ms");
  26. }

}

  1. ```java
  2. 0 cost: 92 ms

AtomicInteger无锁实例

  1. class AccountCas implements Account {
  2. private AtomicInteger balance;
  3. public AccountCas(int balance) {
  4. this.balance = new AtomicInteger(balance);
  5. }
  6. @Override
  7. public Integer getBalance() {
  8. return balance.get();
  9. }
  10. @Override
  11. public void withdraw(Integer amount) {
  12. /*while(true) {
  13. // 获取余额的最新值
  14. int prev = balance.get();
  15. // 要修改的余额
  16. int next = prev - amount;
  17. // 真正修改
  18. if(balance.compareAndSet(prev, next)) {
  19. break;
  20. }
  21. }*/
  22. // 乘以负一就是将正数改为负数,代表减掉amount
  23. balance.getAndAdd(-1 * amount);
  24. }
  25. }
  1. 0 cost: 90 ms

CAS原理

CAS - 图1