原子类

我们可以看到这些getAndAdd这种复杂类型,底层也是运行while true,cas方式来运行
AtomicReference
public class Test32 {public static void main(String[] args) {DecimalAccountCas decimalAccountCas = new DecimalAccountCas(new BigDecimal("10000"));DecimalAccount.demo(decimalAccountCas);}}class DecimalAccountCas implements DecimalAccount{private AtomicReference<BigDecimal> balance;public DecimalAccountCas(BigDecimal balance) {this.balance = new AtomicReference<>(balance);}@Overridepublic BigDecimal getBalance() {return balance.get();}@Overridepublic void withdraw(BigDecimal amount) {while (true){BigDecimal prev = balance.get();BigDecimal next = prev.subtract(amount);if (balance.compareAndSet(prev,next)) {break;}}}}interface DecimalAccount{BigDecimal getBalance();void withdraw(BigDecimal amount);static void demo(DecimalAccount account){List<Thread> ts = new ArrayList<>();long start = System.nanoTime();for (int i = 0;i<1000;i++){ts.add(new Thread(()->{account.withdraw(new BigDecimal("10.00"));}));}ts.forEach(Thread::start);ts.forEach(t->{try{t.join();}catch (Exception e){e.printStackTrace();}});long end = System.nanoTime();System.out.println(account.getBalance() + "cost : " + ((end-start)/1000_000) +" ms");}}
ABA问题
ABA问题解决
static AtomicStampedReference<String> ref = new AtomicStampedReference<>("A",0);public static void main(String[] args) {String s = ref.getReference();int stamp = ref.getStamp();other();try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}boolean c = ref.compareAndSet(s, "C",stamp,stamp+1);System.out.println(c);}public static void other(){new Thread(()->{String reference = ref.getReference();int stamp = ref.getStamp();System.out.println(ref.compareAndSet(reference, "B",stamp,stamp+1));}).start();try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}new Thread(()->{String reference = ref.getReference();int stamp = ref.getStamp();System.out.println(ref.compareAndSet(reference, "A",stamp,stamp+1));}).start();}

