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){
}
}
}
java 线程 SynchBankTransfer00,布布扣,bubuko.com
java 线程 SynchBankTransfer00