zoukankan      html  css  js  c++  java
  • java 线程 SynchBankTransfer01

    package j2se.thread.demo;
    
    
    /**
     * <p>Project:J2SE 的基础知识</p>
     * <p>Tile:多线程模拟银行转账 </p>
     * <p>Description: 
     *    1.在同一个银行中的账户之间进行转账服务 , 站在银行的角度 , 无论咱们转 , 银行里面
     *      的总金额不会变化 ;
     *      
     *    2.将 A 账户里面的金额 , 转向 B 账户 ,这个过程不能被打断 , 须要加锁 , 也就是在同一时刻
     *      仅仅能有一个线程在 运行 转账 这段代码段 ;
     *      
     *    3.通过 synchronized keyword 放到 方法上 , 或者 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 , "accountName@_"+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()+"
    " ) ;
    			
    			
    			// 查询出银行的总金额 
    			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){
    			
    		}
    		
    	}	
    }
    
    
    
    
    

  • 相关阅读:
    前后端分离
    分库分表之终极设计方案
    题解-CF1491
    题解-ARC113
    题解-CF578D LCS Again
    团队冲刺第二阶段5
    团队冲刺第二阶段4
    团队冲刺第二阶段3
    团队冲刺第二阶段2
    团队冲刺第二阶段1
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/7065097.html
Copyright © 2011-2022 走看看