package j2se.thread.demo; /** * <p>Project:J2SE 的基础知识</p> * <p>Tile:多线程模拟银行转账 </p> * <p>Description: * 1.在同一个银行中的账户之间进行转账服务 , 站在银行的角度 , 不管咱们转 , 银行里面 * 的总金额不会变化 ; * * 2.将 A 账户里面的金额 , 转向 B 账户 ,这个过程不能被打断 , 需要加锁 , 也就是在同一时刻 * 只能有一个线程在 执行 转账 这段代码段 ; * * 3.通过 synchronized 关键字 放到 方法上 , 或者 synchronized(this){} 代码块来 实现 加锁 ,保证线程同步 ; * * </p> * * @date 2014-06-07 * @author liwenkai * @version 1.0 * */ public class SynchBankTransfer01{ public static void main(String[] args){ // 最大转账金额 , 也是银行账户初始化金额 double initialBalance = 1000 ; String bankName = "招商银行" ; // 银行中的账户数量 int acctCounts = 100 ; Bank01 bk = new Bank01(bankName ,acctCounts , initialBalance ) ; for(int i = 0 ; i < acctCounts ; i++){ TransferRunnable01 tr = new TransferRunnable01( bk , i , initialBalance ) ; Thread thread = new Thread(tr , ".........线程名 = " + i +" ................") ; thread.start() ; } } } /** * 银行中的账户 */ class Account01{ // 账户ID private int accountId ; // 账户名 private String accountName ; // 账户里面的金额 private double balance ; // constructor methods public Account01(){ } public Account01( 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 "Account01 [accountId=" + accountId + ", accountName=" + accountName + ", balance=" + balance + "]"; } } /** * 银行 */ class Bank01{ private String bankName ; private final Account01[] Account01s ; private double totalBalance ; // constructor methods /** * bankName:银行的名称 * acctCounts:初始化银行中的账户数量 * initialBalance:初始化银行账户中默认的金额 */ public Bank01(String bankName , int acctCounts , double initialBalance){ this.bankName = bankName ; Account01s = new Account01[acctCounts] ; for(int i = 0 ; i < acctCounts ; i++){ Account01s[i] = new Account01( i , "[email protected]_"+i , initialBalance) ; } } /** * 银行转账方法 * @param fromAccId 转出账户ID * @param toAccId 转入账户ID * @param transBalance 转账金额 */ // 也可以 把 synchronized , 加到方法上 ,对整个方法进行加锁 (拿到的是对象锁) ; // public synchronized void transferAccount(int fromAccId , int toAccId , double transBalance){ public void transferAccount(int fromAccId , int toAccId , double transBalance){ if((Account01s[fromAccId].getBalance() - transBalance) < 0 ) return ; // 一般采用 synchronized(this) 代码块 来进行给相应的代码片段加锁 , // 加锁的范围能小则小 , 锁的范围太大的话影响效率 , (拿到的是对象锁) synchronized(this){ 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 = " + Account01s[fromAccId].getBalance() ) ; Account01s[fromAccId].setBalance(Account01s[fromAccId].getBalance() - transBalance) ; System.out.println("---- transfer out account after fromAccount["+fromAccId+"].balance = " + Account01s[fromAccId].getBalance() ) ; System.out.println("---------------------------------transfer in ---------------------------"); System.out.println("---- transfer in account before toAccount["+toAccId+"].balance = " + Account01s[toAccId].getBalance() ) ; Account01s[toAccId].setBalance(Account01s[toAccId].getBalance() + transBalance) ; System.out.println("---- transfer in account after toAccount["+toAccId+"].balance = " + Account01s[toAccId].getBalance()+"\r\n" ) ; // 查询出银行的总金额 System.out.println("---- totalBalance of bank = " +getTotalBalance()+" --------end---" ) ; } } // 计算银行所有账户的总金额 public double getTotalBalance(){ double tmp = 0.0d ; for(Account01 ac : Account01s){ tmp += ac.getBalance() ; } totalBalance = tmp ; return tmp ; } // 银行总的账户数 public int getAccountCounts(){ return Account01s.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 Account01[] getAccount01s() { return Account01s; } } /** * * 执行任务的线程体 */ class TransferRunnable01 implements Runnable{ private Bank01 bk ; private int fromAccId ; private int delay = 1000 ; private double maxTransValue ; // constructor 方法 ; public TransferRunnable01(Bank01 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){ } } }
java 线程 SynchBankTransfer01
时间: 2024-10-25 06:46:50