首頁 > 軟體

java多執行緒實現取款小程式

2022-05-19 19:00:32

最近java學到了多執行緒程式設計中的執行緒同步問題,教材中的取款小程式對於理解執行緒和執行緒同步很有幫助,在此將其補充完善.

1、建立java類

這裡建立了三個java類,第一個Account類,用於封裝賬戶中的各種資訊;第三個DrawThread類用於實現執行緒體;第二個類主要封裝了主函數

2、Account類

public class Account {
    //封裝賬戶編號,賬戶餘額和兩個成員變數
    private String accountNo;
    private double balance;

    public Account(){};
    public Account(String accountNo,double balance){
        this.accountNo=accountNo;
        this.balance=balance;
    }

    public void setAccountNo(String accountNo)
    {
        this.accountNo=accountNo;
    }
    public void setBalance(double balance){
        this.balance=balance;
    }

    public String getAccountNo(){
        return accountNo;
    }
    public double getBalance(){
        return balance;
    }

    public int hashCode(){
        return accountNo.hashCode();
    }

    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;
    }

}

3、DrawThread類

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() {
        //使用account作為同步監視器,任何執行緒進入下面同步程式碼塊之前
        //必須先獲得對account賬戶的鎖定——其他執行緒無法獲得鎖,也就無法修改它
        synchronized (account) {
            if (account.getBalance() >= drawAmount) {
                //吐出鈔票
                System.out.println(getName() + "取錢成功!吐出鈔票:" + drawAmount);
        /*
        try {
           Thread.sleep(1);
           }catch (InterruptedException ex)
        {
            ex.printStackTrace();
        }
        */
                //修改餘額
                account.setBalance(account.getBalance() - drawAmount);
                System.out.println("t餘額為:" + account.getBalance());
            } else {
                System.out.println(getName() + "取錢失敗!餘額不足!");
            }
        }
    }
}

4、DrawTest類

public class DrawTest {
    public static void main(String[] args){
        //建立一個賬戶
        Account acct=new Account("1234567",1000);
        //模擬兩個執行緒對同一個賬戶取錢
        new DrawThread("jack",acct,800).start();
        new DrawThread("rose",acct,800).start();
    }
}

執行結果:

以上程式有一點需要注意,就是用到了同步程式碼塊。它可以解決run()方法不具備同步安全性(即當兩個執行緒同時傳送請求時即會造成異常)

同步程式碼塊:

synchronized (obj){
//需要執行的程式碼
}

如果我們去掉run()方法中的同步程式碼塊,繼續執行

Account acct=new Account("1234567",1000);
new DrawThread("jack",acct,800).start();
new DrawThread("rose",acct,800).start();

(銀行賬戶一共1000元,Jack和rose分別對同一賬戶取錢)

執行結果:

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com