AtomicReference

原子更新引用类型。

  1. public class Test35 {
  2. public static void main(String[] args) {
  3. DecimalAccount.demo(new DecimalAccountCas(new BigDecimal("10000")));
  4. }
  5. }
  6. class DecimalAccountCas implements DecimalAccount {
  7. private AtomicReference<BigDecimal> balance;
  8. public DecimalAccountCas(BigDecimal balance) {
  9. // this.balance = balance;
  10. this.balance = new AtomicReference<>(balance);
  11. }
  12. @Override
  13. public BigDecimal getBalance() {
  14. return balance.get();
  15. }
  16. @Override
  17. public void withdraw(BigDecimal amount) {
  18. while(true) {
  19. BigDecimal prev = balance.get();
  20. BigDecimal next = prev.subtract(amount);
  21. if (balance.compareAndSet(prev, next)) {
  22. break;
  23. }
  24. }
  25. }
  26. }
  27. interface DecimalAccount {
  28. // 获取余额
  29. BigDecimal getBalance();
  30. // 取款
  31. void withdraw(BigDecimal amount);
  32. /**
  33. * 方法内会启动 1000 个线程,每个线程做 -10 元 的操作
  34. * 如果初始余额为 10000 那么正确的结果应当是 0
  35. */
  36. static void demo(DecimalAccount account) {
  37. List<Thread> ts = new ArrayList<>();
  38. for (int i = 0; i < 1000; i++) {
  39. ts.add(new Thread(() -> {
  40. account.withdraw(BigDecimal.TEN);
  41. }));
  42. }
  43. ts.forEach(Thread::start);
  44. ts.forEach(t -> {
  45. try {
  46. t.join();
  47. } catch (InterruptedException e) {
  48. e.printStackTrace();
  49. }
  50. });
  51. System.out.println(account.getBalance());
  52. }
  53. }