设为首页 加入收藏

TOP

Java高性能编程之CAS与ABA及解决方法(四)
2019-09-18 11:10:54 】 浏览:88
Tags:Java 高性能 编程 CAS ABA 解决 方法
int current = unsafe.getIntVolatile(this,valueOffset); if (unsafe.compareAndSwapInt(this,valueOffset,current,current+2)){ break; } } System.out.println("非法组织洗钱,加入2元,余额:"+k); } public void oldSystemTransfer() throws InterruptedException { ABATest abaTest = new ABATest(); System.out.println("账户余额:"+k); new Thread(new Runnable() { @Override public void run() { try { abaTest.transferOld(); } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); Thread.sleep(20); abaTest.cleanMoneyAdd(); Thread.sleep(20); abaTest.cleanMoneySub(); Thread.sleep(200); System.out.println("银行卡原来余额为10,接收转账1元,故期望余额为11元。实际余额:"+abaTest.k); } public static void main(String[] args) throws InterruptedException { ABATest abaTest = new ABATest(); abaTest.oldSystemTransfer(); /** * 运行结果: * 账户余额:10 * 开始转账(旧系统:存在ABA问题) * 由于CPU抢占问题,转账程序阻塞100ms(为了将可能出现的ABA问题,变成肯定出现) * 非法组织洗钱,加入2元,余额:12 * 非法组织洗钱,盗走2元,余额:10 * 银行转账1元,成功。余额:11 * 银行卡原来余额为10,接收转账1元,故期望余额为11元。实际余额:11 */ } }

ABAResolveTest

这是一个修复了ABA问题的示例。示例中银行正常发现客户账户上的非法洗钱行为。


    package tech.jarry.learning.netease.casWithABA;
    
    import java.util.concurrent.atomic.AtomicStampedReference;
    
    /**
     * @Description:
     * @Author: jarry
     */
    public class ABAResolveTest {
    
        private AtomicStampedReference<Integer> kReference = new AtomicStampedReference<>(10,0);
    
        private void transferNew() throws InterruptedException {
            System.out.println("开始转账(新系统:解决了ABA问题)");
            while(true) {
                Integer currentReference = kReference.getReference();
                int stamp = kReference.getStamp();
                System.out.println("由于CPU抢占问题,转账程序阻塞100ms");
                Thread.sleep(100);
                if (kReference.compareAndSet(currentReference,currentReference+1,stamp,stamp+1)){
                    System.out.println("银行转账"+1+"元,成功。余额:"+kReference.getReference());
                    break;
                }
                System.err.println("警告:账户存在交易记录以外的资金流动");
            }
        }
    
        private void cleanMoneySub(){
            int stamp = kReference.getStamp();
            kReference.set(kReference.getReference()+2,stamp+1);
            System.out.println("非法组织洗钱,盗走2元,余额:"+kReference.getStamp());
        }
    
        private void cleanMoneyAdd(){
            int stamp = kReference.getStamp();
            kReference.set(kReference.getReference()-2,stamp+1);
            System.out.println("非法组织洗钱,加入2元,余额:"+kReference.getStamp());
        }
    
        private void newSystemTransfer() throws InterruptedException {
            ABAResolveTest abaResolveTest = new ABAResolveTest();
            System.out.println("账户余额:"+abaResolveTest.kReference.getReference());
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        abaResolveTest.transferNew();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
    
            Thread.sleep(20);
            abaResolveTest.cleanMoneyAdd();
            Thread.sleep(20);
            abaResolveTest.cleanMoneySub();
    
            Thread.sleep(200);
            System.out.println("银行卡原来余额为10,接收转账1元,故期望余额为11元。实际余额:"+abaResolveTest.kReference.getReference());
        }
    
        public static void main(String[] args) throws InterruptedException {
            ABAResolveTest abaResolveTest = new ABAResolveTest();
            abaResolveTest.newSystemTransfer();
            /**
             * 运行结果:
             * 账户余额:10
             * 开始转账(新系统:解决了ABA问题)
             * 由于CPU抢占问题,转账程序阻塞100ms
             * 非法组织洗钱,加入2元,余额:1
             * 非法组织洗钱,盗走2元,余额:2
             * 警告:账户存在交易记录以外的资金流动
首页 上一页 1 2 3 4 5 下一页 尾页 4/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇百度地图WEB端判断用户是否在网格.. 下一篇Java性能 -- CAS乐观锁

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目