多執行緒實現存款取款
阿新 • • 發佈:2018-11-26
多執行緒實現存款取款
我們在做一些比較大的專案的時候,可能需要用到多執行緒,比如我們做一個銀行系統,最基本的操作,存錢,取錢。
當我們跑單執行緒時候存錢取錢無所謂。當我們用多執行緒的時候就會對執行緒的共享資源比如使用者的餘額進行控制,
保證只能存錢程序或者取錢程序中的一個程序去訪問共享資源即餘額。下面看實現:
package Test; class Account { String name; double balance; public Account(String name) { this.name=name; this.balance=0; } public synchronized void put(double value) { if(value>0) this.balance+=value; System.out.println("您的存款金額為"+value+"存款成功,餘額為"+this.balance); } public synchronized double get( double value) { if(value<=0) return 0; if(value<=this.balance) this.balance-=value; else { value=this.balance; this.balance=0; } System.out.println("您的取款金額為"+value+"取款成功,餘額為"+this.balance); return value; } } class SaveThread extends Thread{ private Account account; private double value; public SaveThread(Account account,double value) { this.account=account; this.value=value; } public void run() { try {Thread.sleep(1);} catch(InterruptedException ex) {} this.account.put(this.value); } } class FetchThread extends Thread{ private Account account; private double value; public FetchThread(Account account,double value){ this.account = account; this.value = value; } public void run(){ try{ Thread.sleep(1); } catch(InterruptedException ex){} this.account.get(this.value); } public static void main(String[] args) { // TODO Auto-generated method stub Account wang =new Account("Wang"); (new SaveThread(wang,100)).start(); (new SaveThread(wang,200)).start(); (new FetchThread(wang,300)).start(); } }
我們對get()取錢和put()存錢方法加上了鎖。然後有一個取錢執行緒和存錢執行緒同時執行,由於餘額是共享資源只會允許
一個執行緒來訪問他,所以會有上面執行的結果。
當然由於執行緒的執行順序是不確定的,所以上面程式的結果也可能是這樣的:
也可能是這樣的:
這是由於執行緒執行順序不確定性引起的,而且get取錢函式的寫的是如果餘額大於要取的錢,則取出。如果餘額不夠,
則取出全部餘額。儘管餘額為0,也不會報錯。
提高優先順序來讓執行緒執行的順序有規律也是不可靠的。可以用join來控制先執行哪個執行緒。或者用訊號量來控制。