多線程模擬銀行取款


java源碼展示:

銀行:Account.java
package testsynchrozied;

/**
 * 賬戶類
 * @author superdrew
 *
 */
public class Account {
    private int balance = 600;//余額
    
    //顯示余額
    public int getBalance(){
        return balance;
    }
    
    //取款
    public void draw(int money){
        balance = balance - money;
    }
}
銀行線程:AccountRunnable.java
package testsynchrozied;

public class AccountRunnable implements Runnable{
    Account account = new Account();//取款的賬戶
    
    Object obj = new Object();
    
    public void run() {
        
        synchronized(obj){ //synchronized 同步  加鎖  默認是 open狀態 --close()--open
            
            //省略 300行代碼
            
            if(account.getBalance()>=400){//余額大於400就取錢
                try {
                    Thread.sleep(1);//第一個線程 進入阻塞,取錢了  線程死亡了
                                    //第二個線程 進入阻塞    取錢了  線程死亡了
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                account.draw(400);
                System.out.println("取款成功,當前余額:"+account.getBalance()+"當前線程為:"+Thread.currentThread().getName());
            }else{
                System.out.println("余額不足,當前余額:"+account.getBalance()+"當前線程為:"+Thread.currentThread().getName());
            }
            
            //省略 500行代碼
        }
        //解鎖  釋放鎖
    }
    
    public void method1(){
        synchronized(obj){
            
        }
    }
    
    public void method2(){
        synchronized(account){
            
        }
    }
    
    public void method3(){
        synchronized(account){
            
        }
    }
}
測試銀行取款主線程:TestSynchronized.java
package testsynchrozied;

/**
 * 功能:多個用戶同時對一個賬戶取款
 *         使用線程的同步
 * 
 * 1.設計一個賬戶類   余額,取款,顯示余額
 * 2.取款的線程
 * 3.用戶同時取款
 * 
 * 解決方案1:同步代碼塊  synchronized(account){  .... } 
 * 
 * 總結:1.認識同步監視器             account
 *             synchronized(同步監視器){ ... }
 *          1.必須是引用類型的數據,不能是基本數據類型
 *          2.在同步代碼塊中,不要改變引用類型數據的值,屬性的值可以修改
 *          3.盡量不要使用String 和 包裝類做同步監視器,除非代碼塊中不會改變其內容
 *          4.一般是使用共享資源作為同步監視器  (account)
 *          5.可以新建一個專門的同步監視器  Object  沒有具體的業務含義
 * 
 *         2.之前見過的同步監視器
 *             StringBuffer  Hashtabale  vector
 * 
 *         3.同步代碼塊的執行過程
 *             1.第一個線程來到同步代碼塊,發現同步監視器是open狀態,需要close,進去執行里面的代碼
 *             2.執行里面的代碼發生了一些情況 ,切換(阻塞,就緒),第一個線程失去cpu,鎖 還是close
 *             3.第二個線程來到同步代碼塊,發現同步監視器是close狀態,無法執行,其中的代碼也不能執行,
 *               第二個線程進入阻塞狀態
 *             4.第一個線程再次獲取cpu,接着執行后續代碼,執行完畢,鎖 open  第一個線程進入死亡狀態
 *             5.第二個線程再次獲取cpu,又同步代碼塊,發現鎖是open狀態,執行后續代碼.重復第一個線程的過程
 *     
 *         4.線程同步的有點和缺點
 *             優點:安全
 *             缺點:效率低下,有可能出現死鎖
 *     
 *      5.多個同步代碼塊使用的是同一個同步監視器(鎖),鎖住其中一個代碼塊同時也會鎖住其它的所有使用該同步監視器(鎖)代碼塊
 *          其它線程無法訪問其中任何一個代碼塊
 *          但是沒有鎖住其它的同步監視器代碼塊
 */
public class TestSynchronized {
    public static void main(String[] args) {
        AccountRunnable ar = new AccountRunnable();
        Thread th1 = new Thread(ar);
        th1.setName("Drew");
        Thread th2 = new Thread(ar);
        th2.setName("Super");
        
        th1.start();
        th2.start();

    }
}
結果展示:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM