我给出了一个Banking示例的代码,我试图弄清楚这是否会产生死锁。如果是这样,代码的哪一部分实现了它?我还想知道如何改变代码以防止死锁。我知道这与方法的排序有关,但这段代码特别让我感到困惑。我是网络编程的新手,所以我对这个话题仍然有些困惑。
我用Java写的。
公共类银行{
public Bank(int n, double initialBalance)
{
accounts = new double[n];
Arrays.fill(accounts, initialBalance);
bankLock = new ReentrantLock();
sufficientFunds = bankLock.newCondition();
}
public synchronized void transfer(int from, int to, double amount) throws InterruptedException
{
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());
sufficientFunds.signalAll();
}
finally
{
bankLock.unlock();
}
}
public synchronized 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;
}
公共类DeadlockApp {
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 t = new Thread(r);
t.start();
}
}
当我运行代码时,它非常慢,只产生了两个结果,所以我无法分辨是否是持续的死锁或者我的IDE只是滞后。
死锁的基本要求是两个或多个线程尝试获取一系列锁,但是以不同的顺序获取它们。
你有两个锁,但你的线程都执行相同的代码,它具有固定的锁获取顺序,并且可以递归获取两个锁,因此没有死锁。
更具体地说,由于它是transfer
,一次只有一个线程在synchronized
中执行。
锁按此顺序获取:
没有死锁,所以还有其他原因导致“缓慢”。我的猜测是随机行动需要多长时间来建立足够的资金。