AtomicInteger和AtomicLong这类原子整数主要是针对整数类型的线程安全的,为了实现对原子引用的线程安全,引入了AtomicReference这个原子引用类
- 还是拿1000个线程同时取10块钱的案例举例,代码如下所示:
public interface Account { public BigDecimal getBalance(); public void withdraw(BigDecimal amount); static void demo(Account account) { List<Thread> threads = new ArrayList<>(); for (int i=0;i<1000;i++) { threads.add(new Thread(() -> { account.withdraw(BigDecimal.TEN); })); } threads.forEach(Thread::start); long start = System.nanoTime(); for (Thread thread : threads) { try { thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } long end = System.nanoTime(); System.out.println("余额 " + account.getBalance() + " ---" + " cost " + (end - start)/1000000 + "ms"); } }
具体实现类如下所示:
class AccountReference implements Account { private AtomicReference<BigDecimal> balance; // 通过AtomicReference 对结果进行包装 public AccountReference(BigDecimal balance) { this.balance = new AtomicReference<>(balance); } @Override public BigDecimal getBalance() { return this.balance.get(); } @Override public void withdraw(BigDecimal amount) { while (true) { BigDecimal prev = balance.get(); BigDecimal next = prev.subtract(amount); if (balance.compareAndSet(prev, next)) { // 这条语句是原子性的 break; } } } } class Test { public static void main(String[] args) { Account.demo(new AccountReference(new BigDecimal(10000))); } }
2.运行结果
文章评论