java 线程 SynchBankTransfer00

来源:互联网 发布:域名备案进度查询 编辑:程序博客网 时间:2024/06/09 22:43
package j2se.thread.demo;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;/** * <p>Project:J2SE 的基础知识</p> * <p>Tile:多线程模拟银行转账 </p> * <p>Description: *    1.在同一个银行中的账户之间进行转账服务 , 站在银行的角度 , 不管咱们转 , 银行里面 *      的总金额不会变化 ; *       *    2.将 A 账户里面的金额 , 转向 B 账户 ,这个过程不能被打断 , 需要加锁 , 也就是在同一时刻 *      只能有一个线程在 执行 转账 这段代码段 ; *       *    3.通过 java.util.concurrent.locks.ReentrantLock 类中的方法 , 实现 加锁 ,保证线程同步 ; *               * </p> * * @date 2014-06-04 * @author liwenkai * @version 1.0 * */public class SynchBankTransfer00{        public static void main(String[] args){        // 最大转账金额 , 也是银行账户初始化金额        double initialBalance = 1000 ;        String bankName = "招商银行" ;        // 银行中的账户数量        int acctCounts = 100 ;                Bank00 bk = new Bank00(bankName ,acctCounts , initialBalance ) ;                for(int i = 0 ; i < acctCounts ; i++){                        TransferRunnable00 tr = new TransferRunnable00( bk  , i , initialBalance ) ;            Thread thread = new Thread(tr , ".........线程名 = " + i +" ................") ;            thread.start() ;        }        //        System.out.printf("%10.5f  , %d , %d%n ", 100.4677 , 60 , 99 ) ;//        System.out.printf("%10.3f  , %d , %d ", 999.4677 , 70 , 100 ) ;//        //        /**//          100.46770  , 60 , 99//             999.468  , 70 , 100//        */                         }}/** * 银行中的账户 */class Account00{        // 账户ID    private  int accountId ;    // 账户名    private  String accountName ;    // 账户里面的金额    private  double balance ;        // constructor methods    public Account00(){            }        public Account00( int  accountId , String accountName, double balance) {                this.accountId = accountId;        this.accountName = accountName;        this.balance = balance;    }        // gets and sets methods    public int getAccountId() {        return accountId;    }    public void setAccountId(int accountId) {        this.accountId = accountId;    }    public String getAccountName() {        return accountName;    }    public void setAccountName(String accountName) {        this.accountName = accountName;    }    public double getBalance() {        return balance;    }    public void setBalance(double balance) {        this.balance = balance;    }    @Override    public String toString() {        return "Account00 [accountId=" + accountId + ", accountName="                + accountName + ", balance=" + balance + "]";    }                }/** * 银行 */class Bank00{        private  String bankName ;    private  final  Account00[] account00s ;    private  double totalBalance  ;    private  Lock  lock = new  ReentrantLock() ;            // constructor methods    /**     * bankName:银行的名称     * acctCounts:初始化银行中的账户数量     * initialBalance:初始化银行账户中默认的金额     */    public Bank00(String  bankName  , int acctCounts  , double  initialBalance){        this.bankName = bankName ;        account00s = new Account00[acctCounts] ;                for(int i = 0 ; i < acctCounts ; i++){                        account00s[i] = new Account00( i , "accountName@_"+i , initialBalance) ;        }            }            /**     * 银行转账方法     * @param fromAccId 转出账户ID     * @param toAccId   转入账户ID     * @param transBalance 转账金额     */    public void transferAccount(int fromAccId , int toAccId , double transBalance){                if((account00s[fromAccId].getBalance() - transBalance) < 0  ) return ;        //加锁,一直到解锁,这些代码不可能被打断        lock.lock() ;                try{            System.out.println("---- Current Thread Name = " + Thread.currentThread().getName() + " , " +" Current Time = " + System.currentTimeMillis()) ;            System.out.println("---- parameter [ fromAccId:" +fromAccId +" , "                                                 + " toAccId: " +toAccId+" , "                                                 + " transBalance:" + transBalance                                                 + "]") ;            System.out.println("---------------------------------transfer out ---------------------------");            System.out.println("---- transfer out account before  fromAccount["+fromAccId+"].balance = " + account00s[fromAccId].getBalance() ) ;                        account00s[fromAccId].setBalance(account00s[fromAccId].getBalance() - transBalance) ;                        System.out.println("---- transfer out account after  fromAccount["+fromAccId+"].balance = " + account00s[fromAccId].getBalance() ) ;                        System.out.println("---------------------------------transfer in ---------------------------");                        System.out.println("---- transfer in account before  toAccount["+toAccId+"].balance = " + account00s[toAccId].getBalance() ) ;                        account00s[toAccId].setBalance(account00s[toAccId].getBalance() + transBalance) ;                        System.out.println("---- transfer in account after  toAccount["+toAccId+"].balance = " + account00s[toAccId].getBalance()+"\r\n" ) ;                                    // 查询出银行的总金额            System.out.println("---- totalBalance of bank  = " +getTotalBalance()+" --------end---" ) ;                    }finally{            //解锁            lock.unlock() ;        }        }            // 计算银行所有账户的总金额    public double getTotalBalance(){        double tmp = 0.0d ;        for(Account00 ac : account00s){                        tmp += ac.getBalance() ;        }        totalBalance = tmp ;        return tmp ;            }        // 银行总的账户数    public int getAccountCounts(){                return account00s.length ;    }            // gets and sets methods    public String getBankName() {        return bankName;    }    public void setBankName(String bankName) {        this.bankName = bankName;    }        public void setTotalBalance(double totalBalance) {        this.totalBalance = totalBalance;    }    public Account00[] getAccount00s() {        return account00s;    }        }/** * * 执行任务的线程体 */class  TransferRunnable00 implements Runnable{            private Bank00 bk ;    private int fromAccId ;    private int delay = 1000 ;    private double maxTransValue  ;        // constructor 方法 ;    public TransferRunnable00(Bank00 bk  , int fromAccId , double maxTransValue ){        this.bk = bk ;        this.fromAccId = fromAccId ;        this.maxTransValue =  maxTransValue ;            }        //    public  void run(){        try{            while(true){                int toAccId = (int)(bk.getAccountCounts()*Math.random()) ;                double    transBalance = maxTransValue*Math.random() ;                    bk.transferAccount(fromAccId, toAccId, transBalance) ;                Thread.sleep((long)(delay*Math.random())) ;            }                    }catch(InterruptedException e){                    }            }    }


0 0
原创粉丝点击