网上瞎说的很多,真正解决了问题,注释也写的清清楚楚。也直接拷贝运行,我就比较反感帖代码不帖全的。
package LearnCases; import java.math.BigDecimal; import java.util.concurrent.atomic.AtomicStampedReference; /** * Created with IntelliJ IDEA. * * @Auther: suibin * @Date: 2021/04/27/23:13 * @Description:原子计数,原子金额 */ public class AtomicStampedReferenceDemo { //原子计数器,统计在线人数,在线+1,离线-1。库存的计数。 static class AtomicCounter{ private static AtomicStampedReference<Integer> count = new AtomicStampedReference<Integer>(0, 0); public static int getCount() { return count.getReference(); } public static int increment() { int[] stamp = new int[1]; while(true) { Integer value = count.get(stamp); //同时获取时间戳和数据,防止获取到数据和版本不是一致的 int newValue = value + 1; boolean writeOk = count.compareAndSet(value, newValue, stamp[0], stamp[0] + 1); if(writeOk) { return newValue; } } } public static int decrement() { int[] stamp = new int[1]; while(true) { Integer value = count.get(stamp);//同时获取时间戳和数据,防止获取到数据和版本不是一致的 int newValue = value - 1; boolean writeOk = count.compareAndSet(value, newValue, stamp[0], stamp[0] + 1); if(writeOk) { return newValue; } } } } //原子账户 static class AtomicMoney{ private static AtomicStampedReference<BigDecimal> count =null; //初始化金额 public static void getInitialization(BigDecimal intMoney) { //If instance has not been created yet, create it if (count == null) { synchronized (AtomicMoney.class) { if (count == null) { count=new AtomicStampedReference<BigDecimal>(intMoney, 0); } } } } public static BigDecimal getCount() { return count.getReference(); } public static BigDecimal increment(BigDecimal money) { int[] stamp = new int[1]; while(true) {//有失败的情况,自旋 BigDecimal value = count.get(stamp); //同时获取时间戳和数据,防止获取到数据和版本不是一致的 BigDecimal newValue = value.add(money);//加上金额 boolean writeOk = count.compareAndSet(value, newValue, stamp[0], stamp[0] + 1); if(writeOk) { return newValue; } } } public static BigDecimal decrement(BigDecimal money) { int[] stamp = new int[1]; while(true) { BigDecimal value = count.get(stamp);//同时获取时间戳和数据,防止获取到数据和版本不是一致的 BigDecimal newValue = value.subtract(money);//减去金额 boolean writeOk = count.compareAndSet(value, newValue, stamp[0], stamp[0] + 1); if(writeOk) { return newValue; } } } } public static void main(String[] args) throws InterruptedException { //启动10000个线程 for (int i = 0; i < 10000; i++) { Thread t1 = new Thread(new Runnable() { @Override public void run() { //计数增加了10000次 AtomicCounter.increment(); //计数减少了10000次 AtomicCounter.decrement(); //初始化1000元 AtomicMoney.getInitialization(new BigDecimal("1000")); //增加了10000个200.43元 AtomicMoney.increment(new BigDecimal("200.43")); //减少了10000个140.22元 AtomicMoney.decrement(new BigDecimal("140.22")); } }); t1.start(); t1.join(); } System.out.println("最终计数:"+AtomicCounter.getCount()); System.out.println("最终账户金额:"+AtomicMoney.getCount()); } }
运行结果: