最近同事在用线程,探索一下线程同步
public class SynchBankTest {
public static final int NACCOUNTS = 100;
public static final double INITIAL_BALANCE = 1000;
public static void main(String[] args) {
Bank2 b = new Bank2(NACCOUNTS, INITIAL_BALANCE);
int i;
for (i = 0; i < NACCOUNTS; i++) {
TransferRunable2 r = new TransferRunable2(b, i, INITIAL_BALANCE);
Thread t = new Thread(r);
t.start();
}
}
}
class TransferRunable2 implements Runnable {
private Bank2 bank;
private int fromAccount;
private double maxAmount;
private int DELAY = 10;
/**
* 转账线程实现类构造方法
*
* @param b
* 转账银行
* @param from
* 转出账户
* @param max
* 每笔转账最大金额
*/
public TransferRunable2(Bank2 b, int from, double max) {
bank = b;
fromAccount = from;
maxAmount = max;
}
public void run() {
try {
while (true) {
int toAccount = (int) (bank.size() * Math.random());
double amount = maxAmount * Math.random();
bank.transfer(fromAccount, toAccount, amount);
Thread.sleep((int) (DELAY * Math.random()));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Bank2 {
//构建一个可被用来保护临界区的可重入锁
private Lock BankLock;
private Condition sufficient;
private final double[] accounts;
/**
* 银行类
*
* @param n
* 账户数量
* @param initialBalance
* 账户初始余额
*/
public Bank2(int n, double initialBalance) {
BankLock = new ReentrantLock();
//余额不足的条件变量
sufficient = BankLock.newCondition();
accounts = new double[n];
for (int i = 0; i < accounts.length; i++) {
accounts[i] = initialBalance;
}
}
/**
* 转账方法
*
* @param from
* 转出账户
* @param to
* 转入账户
* @param amount转账金额
*/
public void transfer(int from, int to, double amount) {
BankLock.lock();
try {
while (accounts[from] < amount)
sufficient.await();//余额不足线程等待
System.out.println(Thread.currentThread().getName());
accounts[from] -= amount;
System.out.printf("%10.2f from %d to %d", amount, from, to);
accounts[to] += amount;
System.out.printf("Total Balance %10.2f%n", getTotalBalance());
sufficient.signalAll();//唤醒等待线程
} catch (Exception e) {
e.printStackTrace();
} finally {
BankLock.unlock();//释放锁
}
}
/**
* 获取所有账户余额之和
*
* @return 总余额
*/
public double getTotalBalance() {
BankLock.lock();
try {
double sum = 0;
for (double a : accounts) {
sum += a;
}
return sum;
} finally {
BankLock.unlock();
}
}
/**
* 获取该银行有多少账户
*
* @return 账户数量
*/
public int size() {
return accounts.length;
}
}
}