public class UnsynchBankTest {
public static final int NACCOUNTS = 100;
public static final double INITIAL_BALANCE = 1000;
public static final double MAX_AMOUNT = 1000;
public static final int DELAY = 10;
public static void main(String[] args) {
Bank bank = new Bank(NACCOUNTS, INITIAL_BALANCE);//创建一个银行对象;这个银行有一百个用户;一百个用户使用这个银行
for (int i = 0; i < NACCOUNTS; i++) {
int fromAccount = i;
Runnable r = () -> {
try
{
while (true) {
int toAccount = (int) (bank.size() * Math.random());//拿出一个随机账户
double amount = MAX_AMOUNT * Math.random();//设定随机一笔钱(支出/得到)
bank.transfer(fromAccount, toAccount, amount);//转账操作
Thread.sleep((int) (DELAY * Math.random()));//随机的休眠时间
}
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();//加上这句为好
}
};
Thread t = new Thread(r);//创建一个线程;该线程处于创建状态
t.start();//使线程处于可运行的状态(可能运行,也可能处于阻塞状态)
}
}
}
import java.util.Arrays;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Bank {
private final double[] accounts;
private Lock bankLock;
private Condition sufficientFunds;
public Bank(int n, double initialBalance) {
accounts = new double[n];//n个账户
Arrays.fill(accounts, initialBalance);//每个账户初始资金为1000元
bankLock = new ReentrantLock();//建立锁对象(避免线程共享的bank对象内容发生混乱)
sufficientFunds = bankLock.newCondition();//建立条件对象(便于得到锁对象的线程在不能做有用的工作时对该线程进行处理)
}
public void transfer(int from, int to, double amount) throws InterruptedException {//所有线程都共享一个bank对象
bankLock.lock();//上锁;一个线程正在执行这条语句下方语句(得到锁);其它线程就会在这里停顿(没有得到锁)
try
{//临界区
while (accounts[from] < amount)//这个账户余额不满足支出时
sufficientFunds.await();//条件对象调用该方法使该线程进入条件的等待集(只有被唤醒时才又有可能得到锁,没被唤醒即便锁可用也不能同其它线程竞争)
System.out.print(Thread.currentThread());//打印当前线程信息
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());//因为getTotalBalance()方法在被保护(上锁)的代码中;所以这个方法也得上锁才能被调用
sufficientFunds.signalAll();//唤醒所有等待的线程(使这些线程处于可运行的状态)
}
finally
{
bankLock.unlock();//保护代码块执行完毕,释放锁
}
}
public double getTotalBalance() {//该方法在上面的保护代码块中被调用,所以这个方法也得上锁
bankLock.lock();//上锁
try
{
double sum = 0;
for (double a : accounts)
sum += a;
return sum;
}
finally
{
bankLock.unlock();//释放锁
}
}
public int size() {
return accounts.length;
}
}
点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦