java 线程 SynchBankTransfer00

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){
            
        }
        
    }    
}






©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页