我的任务是实现实时锁定。我已经创建了简单的应用程序。看来效果很好。下一个任务是开发应用程序,从而确定了活锁问题。为此,我计划在代码中输入一个随机值的变量。但是首先,我在BankAccount#tryTransfer(...)中注意到了一些意外的情况。代码字符串this.lock.unlock();
(在Thread.sleep(3_000);
之前)不会释放锁。为什么?有什么帮助吗?预先感谢!
BankAccount.java:
package com.example.livelock;
import java.util.concurrent.locks.*;
public class BankAccount {
private int id;
private double balance;
private Lock lock = new ReentrantLock();
public BankAccount(int id, double balance) {
this.id = id;
this.balance = balance;
}
private boolean decreaseMoney(double amount) throws InterruptedException {
if(lock.tryLock()){
Thread.sleep(500);
balance = balance - amount;
return true;
}
return false;
}
private boolean increaseMoney(double amount) throws InterruptedException {
if(lock.tryLock()){
Thread.sleep(500);
balance = balance + amount;
return true;
}
return false;
}
public void tryTransfer(BankAccount toAccount, double amount) throws InterruptedException {
while(true){
if(this.decreaseMoney(amount)){
if(!toAccount.increaseMoney(amount)){
this.increaseMoney(amount);
this.lock.unlock();
Thread.sleep(3_000);
System.out.println(Thread.currentThread().getName() + " is trying to perform transaction, while " + this.lock.toString().replace("java.util.concurrent.locks.", "") + " | " + toAccount.lock.toString().replace("java.util.concurrent.locks.", ""));
continue;
}
toAccount.unlock();
this.lock.unlock();
break;
}
}
}
public void unlock(){
lock.unlock();
}
}
Transaction.java:
package com.example.livelock;
public class Transaction extends Thread {
private BankAccount fromAccount;
private BankAccount toAccount;
private double amount;
public Transaction(String name, BankAccount fromAccount, BankAccount toAccount, double amount) {
super(name);
this.fromAccount = fromAccount;
this.toAccount = toAccount;
this.amount = amount;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
System.out.println(name + " has started");
try {
fromAccount.tryTransfer(toAccount, 10);
System.out.println(name + ": money is transfered");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + " has finished");
}
}
Tester.java:
package com.example.livelock;
public class Tester {
public static void main(String[] args) throws InterruptedException {
String name = Thread. currentThread().getName();
System.out.println(name + " has started");
BankAccount account1 = new BankAccount(1, 100);
BankAccount account2 = new BankAccount(2, 100);
Transaction th1 = new Transaction("thread-1", account1, account2, 10);
Transaction th2 = new Transaction("thread-2", account2, account1, 10);
th1.start();
th2.start();
Thread.sleep(30_000);
System.out.println(name + " has finished");
}
}