1. 程式人生 > >執行緒安全經典案例:銀行取錢問題

執行緒安全經典案例:銀行取錢問題

銀行取錢的基本流程基本上可以分為如下幾個步驟。
(1)使用者輸入賬戶、密碼,系統判斷使用者的賬戶、密碼是否匹配。
(2)使用者輸入取款密碼
(3)系統判斷賬戶餘額是否大於取款餘額
(4)如果餘額大於取款餘額,則取錢成功;如果餘額小於取款餘額,則取錢失敗。

1、先定義一個賬戶類,該賬戶類封裝了賬號和餘額兩個例項變數。


public class Account {
    private String accountNo;
    private double balance;
    public Account() {

    }
    public Account(String accountNo, double
balance) { super(); this.accountNo = accountNo; this.balance = balance; } public String getAccountNo() { return accountNo; } public void setAccountNo(String accountNo) { this.accountNo = accountNo; } public double getBalance() { return
balance; } public void setBalance(double balance) { this.balance = balance; } @Override public int hashCode() { return accountNo.hashCode(); } @Override public boolean equals(Object obj) { if(this==obj) return true; if(obj != null
&& obj.getClass() == Account.class){ Account target=(Account)obj; return target.getAccountNo().equals(accountNo); } return false; } }

2、提供一個取錢的執行緒類,該執行緒類根據根據執行賬戶、取錢數量進行取錢操作,取錢的邏輯是當其餘額不足時無法提取現金,當餘額足夠時系統吐出鈔票,餘額減少。


public class DrawThread extends Thread{
    private Account account;
    private double drawAmount;
    public DrawThread(String name,Account account, double drawAmount) {
        super(name);
        this.account = account;
        this.drawAmount = drawAmount;
    }
    public void run(){
        if(account.getBalance()>=drawAmount){
            System.out.println(getName()+":取錢成功!吐出鈔票:"+drawAmount);
            try{
                Thread.sleep(1000);
            }catch(InterruptedException e){
                e.printStackTrace();
            }
            account.setBalance(account.getBalance()-drawAmount);
            System.out.println("\t餘額為:"+account.getBalance());
        }else{
            System.out.println(getName()+"取錢失敗!餘額不足!");
        }
    }
}

3、主程式建立一個賬戶,啟動兩個執行緒,執行取錢操作。

public class DrawTest {
    public static void main(String[] args) {
        Account acct=new Account("0329",1000);
        new DrawThread("老張",acct,800).start();
        new DrawThread("老王",acct,800).start();
    }
}
後臺輸出:
    老張:取錢成功!吐出鈔票:800.0
    老王:取錢成功!吐出鈔票:800.0
        餘額為:200.0
        餘額為:-600.0

    注意:程式中有兩個併發執行緒在修改Account物件,系統恰好在try-catch處執行執行緒切換,切換給另一個修改Account物件的執行緒,所以出現了問題。

解決方案:
    Java的多執行緒支援引入了同步監視器來解決這個問題,使用同步監視器的通用方法就是同步程式碼塊。同步程式碼塊的語法格式如下:
    synchronized(obj){

    }

synchronized(account){
            if(account.getBalance()>=drawAmount){
                System.out.println(getName()+":取錢成功!吐出鈔票:"+drawAmount);
                try{
                    Thread.sleep(1000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
                account.setBalance(account.getBalance()-drawAmount);
                System.out.println("\t餘額為:"+account.getBalance());
            }else{
                System.out.println(getName()+"取錢失敗!餘額不足!");
            }
        }
後臺輸出:
    老張:取錢成功!吐出鈔票:800.0
        餘額為:200.0
    老王取錢失敗!餘額不足!

相關推薦

執行安全經典案例銀行問題

銀行取錢的基本流程基本上可以分為如下幾個步驟。 (1)使用者輸入賬戶、密碼,系統判斷使用者的賬戶、密碼是否匹配。 (2)使用者輸入取款密碼 (3)系統判斷賬戶餘額是否大於取款餘額 (4)如果餘額大於取款餘額,則取錢成功;如果餘額小於取款餘額,則取錢失敗。

執行例項模仿人在銀行

package thread; public class Bank{  private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public Ba

(轉)PHP執行安全與非執行安全的區別如何選擇用哪一個?

PHP執行緒安全與非執行緒安全的區別:如何選擇用哪一個? 很多時候,我們在做PHP環境配置的時候,很多人都是直接去亂下載PHP版本的,但是他不清楚:從2000年10月20日釋出的第一個Windows版的PHP3.0.17開始的都是執行緒安全的版本,直至5.2.1版本開始有Thread Safe

執行經典案例模仿儲戶

銀行取錢肯定不能透支這個是眾所周知的,實現此功能就需要藉助多執行緒的知識! 先來看一下采取同步措施前產生的結果: 好的,我們先來定義一個賬戶類: /** * 賬戶類,含卡號,還有餘額 通過同步方法防止出現餘額為負的情況 * * @author Mr.Gao *

Java多執行之併發安全經典案例-賣票

執行緒相關知識 1.建立執行緒的兩種方式 繼承Thread類。 實現Runnable介面。(這種方式較為常用) 2.實現Runnable介面的好處 將執行緒的任務從執行緒的子類中分

33-多執行緒--賣票示例+執行緒安全(產生原因+解決方式同步)+同步(同步程式碼塊+同步的好處與弊端+同步的前提+同步函式+賣票示例的同步函式寫法+驗證同步函式的鎖+驗證靜態同步函式的鎖)

一、賣票示例 需求:四個視窗,同時售賣100張票,票號為1-100 1、沒有多執行緒時的賣票程式碼 class Ticket { //100張票 private int num = 100; public void sale() { /

高併發程式設計執行安全和ThreadLocal

執行緒安全的概念:當多個執行緒訪問某一個類(物件或方法)時,這個類始終都能表現出正確的行為,那麼這個類(物件或方法)就是執行緒安全的。 執行緒安全 說的可能比較抽象,下面就以一個簡單的例子來看看什麼是執行緒安全問題。 public class MyThread impleme

Java面試題Servlet是執行安全的嗎?

轉自: http://www.cnblogs.com/chanshuyi/p/5052426.html   Servlet不是執行緒安全的。 要解釋為什麼Servlet為什麼不是執行緒安全的,需要了解Servlet容器(即Tomcat)使如何響應HTTP請求的。

讀書筆記 ---- 《深入理解Java虛擬機器》---- 第12篇執行安全與鎖優化

上一篇:Java記憶體模型與執行緒:https://blog.csdn.net/pcwl1206/article/details/84661639 目  錄: 1  Java語言中的執行緒安全  1.1  不可變  1.2 

(四)多執行說學逗唱執行險惡,變數和執行安全不得不防

(一)多執行緒說學逗唱:關於執行緒那不得不說的二三事 (二)多執行緒說學逗唱:新手村偶遇Thread類 (三)多執行緒說學逗唱:村口的老R頭是個掃地僧(Runnable) 出了新手村,以後的路可就不那麼好走了,到底現在也是個江湖人,都必須經歷點困難挫折,要不以後拿什

第100次提醒++ 不是執行安全

目錄 寫在前面 一道簡單執行緒安全題,不知道有多少人答不上來 實驗:併發的自增運算 ++ 運算的原理 Java 的原子操作類 寫在最後 瘋狂創客圈 Java 死磕系列 瘋狂創客圈 Java 分散式聊天室【 億級流量】實戰系列之 -17【 部落格園 總入口 】 原始

面試題剖析單例設計模式執行安全問題

本文作者:黃海燕,叩丁狼高階講師。原創文章,轉載請註明出處。 1. volatile 關鍵字 1.1 volatile 關鍵字作用: 在百度百科擷取的描述如下: 叩丁狼教育.png 說明volatile 關鍵字作用作用有兩點: 防止指令重

Java基礎由JVM記憶體模型詳解執行安全

1.前言 最近在研究JVM記憶體模型和Java基礎知識。主要講的是執行緒共享變數與執行緒私有變數以及如何寫出執行緒安全的程式碼。這裡列出一條規則,“類中的成員變數,也叫例項變數,也叫全域性變數,它是非執行緒安全,是所有執行緒共享的變數,定義在方法中的私有變數是執行緒安全的,是每個執行緒私

Java併發程式設計執行安全和ThreadLocal

執行緒安全的概念:當多個執行緒訪問某一個類(物件或方法)時,這個類始終都能表現出正確的行為,那麼這個類(物件或方法)就是執行緒安全的。 執行緒安全 說的可能比較抽象,下面就以一個簡單的例子來看看什麼是執行緒安全問題。 public class MyThread

java多執行2區域性變數的執行安全,實列變數的非執行安全

java多執行緒2:區域性變數的執行緒安全,實列變數的非執行緒安全 “非執行緒安全“就是在多個執行緒訪問同一個物件的例項變數進行併發訪問時候發生,產生的後果就是”髒讀“,也就是取到的資料其實是被修改過的。 a.多執行緒訪問區域性變數是執行緒安全的。 package multiThread

深入理解 GIL如何寫出高效能及執行安全的 Python 程式碼

6歲時,我有一個音樂盒。我上緊發條,音樂盒頂上的芭蕾舞女演員就會旋轉起來,同時,內部裝置發出“一閃一閃亮晶晶,滿天都是小星星”的叮鈴聲。那玩意兒肯定俗氣透了,但我喜歡那個音樂盒,我想知道它的工作原理是什麼。後來我拆開了,才看到它裡面一個簡單的裝置,機身內部鑲嵌著一個拇指大小的金

周海漢標準模板庫stl 容器的執行安全

2007-12-05 周海漢/文 標準模板庫現在應用越來越廣泛。但它的容器是不是執行緒安全的呢?我們看到Windows平臺VC用的PJ STL,MSDN是這樣說的: Thread Safety in the Standard

單例模式的七種寫法, 面試題執行安全的單例模式

http://cantellow.iteye.com/blog/838473 http://meizhi.iteye.com/blog/537563 第一種(懶漢,執行緒不安全): Java程式碼   public class Singleton {  

高併發下執行安全的單例模式(最全最經典

在所有的設計模式中,單例模式是我們在專案開發中最為常見的設計模式之一,而單例模式有很多種實現方式,你是否都瞭解呢?高併發下如何保證單例模式的執行緒安全性呢?如何保證序列化後的單例物件在反序列化後任然是單例的呢?這些問題在看了本文之後都會一一的告訴你答案,趕快來閱讀吧! 什麼

高併發環境下執行安全的單例模式(最全最經典

在所有的設計模式中,單例模式是我們在專案開發中最為常見的設計模式之一,而單例模式有很多種實現方式,你是否都瞭解呢?高併發下如何保證單例模式的執行緒安全性呢?如何保證序列化後的單例物件在反序列化後任然是單例的呢?這些問題在看了本文之後都會一一的告訴你答案,趕快來閱讀吧!什麼是單