2019-07-10

場景練習(xí)一:

轉(zhuǎn)賬功能

描述:
小新轉(zhuǎn)100給小明,同時小紅轉(zhuǎn)50給小新
原有賬戶余額


image.png

代碼初版設(shè)計(jì)
轉(zhuǎn)賬功能:

private static void transfer(Account from, Account to, BigDecimal amount) {
        if (null == from || null == to || null == amount) {
            log.info("【轉(zhuǎn)賬】失敗.參數(shù)不正確");
        }
        synchronized (from) {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                log.error("異常", e);
            }
            synchronized (to) {
                from.setBalance(from.getBalance().subtract(amount));

                to.setBalance(to.getBalance().add(amount));

            }
        }
    }

主函數(shù)調(diào)用

        Account xiaoming = new Account("1", BigDecimal.valueOf(100), "小明");
        Account xiaohong = new Account("2", BigDecimal.valueOf(200), "小紅");
        Account xiaoxin = new Account("3", BigDecimal.valueOf(300), "小新");

        System.out.println("小明轉(zhuǎn)賬前:" + xiaoming.toString());
        System.out.println("小紅轉(zhuǎn)賬前:" + xiaohong.toString());
        System.out.println("小新轉(zhuǎn)賬前:" + xiaoxin.toString());

        List<Future<Integer>> results = new ArrayList<>();
        results.add(executor.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                transfer(xiaoxin, xiaoming, BigDecimal.valueOf(100));
                return 1;
            }
        }));
        results.add(executor.submit(new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                transfer(xiaohong, xiaoxin, BigDecimal.valueOf(50));
                return 1;
            }
        }));

        for (Future<Integer> result : results) {
            try {
                result.get();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        System.out.println("------------------------------");
        System.out.println("小明轉(zhuǎn)賬后:" + xiaoming.toString());
        System.out.println("小紅轉(zhuǎn)賬后:" + xiaohong.toString());
        System.out.println("小新轉(zhuǎn)賬后:" + xiaoxin.toString());

結(jié)果:

小明轉(zhuǎn)賬前:Account(id=1, balance=100, name=小明)
小紅轉(zhuǎn)賬前:Account(id=2, balance=200, name=小紅)
小新轉(zhuǎn)賬前:Account(id=3, balance=300, name=小新)
------------------------------
小明轉(zhuǎn)賬后:Account(id=1, balance=200, name=小明)
小紅轉(zhuǎn)賬后:Account(id=2, balance=150, name=小紅)
小新轉(zhuǎn)賬后:Account(id=3, balance=250, name=小新)

看起來好像沒啥問題,可是會造成死鎖?。?!
設(shè)想,如果是兩個線程,線程A跑小新轉(zhuǎn)給小明100,線程B跑小明轉(zhuǎn)給小新50.這樣線程A先獲取小新這個賬戶鎖,同時線程B獲取小明這個賬戶鎖,雙方都拿了對方需要的鎖,這樣就相處等待??

所以呢,要改進(jìn)一下,改進(jìn)方法很多,可以采用lock獲取鎖失敗直接拒絕策略?;蛘咭部梢园凑找欢樞蚣渔i,這樣大家加鎖策略就都一致啦~~
優(yōu)化版:

private static void transferSuccess(Account from, Account to, BigDecimal amount) {
        if (null == from || null == to || null == amount) {
            log.info("【轉(zhuǎn)賬】失敗.參數(shù)不正確");
        }

        Account min = from.getId().compareTo(to.getId()) > 0 ? to : from;
        Account max = from.getId().compareTo(to.getId()) > 0 ? from : to;

        synchronized (min) {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (max) {
                from.setBalance(from.getBalance().subtract(amount));

                to.setBalance(to.getBalance().add(amount));
            }
        }
    }

??

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 毫無疑問,Spring Cloud 是目前微服務(wù)架構(gòu)領(lǐng)域的翹楚,無數(shù)的書籍博客都在講解這個技術(shù)。 不過大多數(shù)講解還...
    李紹俊閱讀 445評論 0 0
  • 周末,天氣十分晴朗,陽光柔柔,清風(fēng)悠悠,鳥鳴啾啾,花香飄遠(yuǎn)。 我一個人走在路上閑逛,走著走著,忽然看到路邊的紅梅開...
    木蘭溪閱讀 484評論 0 5
  • 感恩今天光棍節(jié),成就了太多商家,讓更多人消費(fèi) 感恩婆婆包的包子和咸卷,很美味 感恩美容院的朋友們 給我機(jī)會介紹項(xiàng)目...
    十八菩提子閱讀 204評論 0 1
  • 前言: 大家在做安卓項(xiàng)目時肯定都會碰到數(shù)據(jù)庫存儲,原生的效率上會比較低,為了提高開發(fā)效率,大多公司會用一些框架,目...
    因?yàn)槲业男?/span>閱讀 1,119評論 0 1

友情鏈接更多精彩內(nèi)容