Моей задачей было реализовать livelock. Я создал простое приложение. Кажется, работает нормально. Следующей задачей была разработка приложения, которое решило проблему с livelock. Для этого я планирую ввести в свой код переменную со случайным значением. Но сначала я заметил в 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");
}
}