I am trying to implement a banking system where I have a set of accounts. There are multiple threds trying to transfer money between accounts, while one thread continuosuly (or rather, at random times) tries to sum up the total money in the bank (Sum of all accounts balance).
The way to solve that sounded obvious at first; Using ReentrantReadWriteLocks
with readLock
for the threads doing the transactions and writeLock
for the thread doing the summation. However after implementing it that way (see code below), I saw a huge drop in performance / "transaction-throughput" even versus doing transactions with only one thread.
Code for above mentioned implementation:
public class Account implements Compareable<Account>{ private int id; private int balance; public Account(int id){ this.id = id; this.balance = 0; } public synchronized int getBalance(){ return balance; } public synchronized setBalance(int balance){ if(balance < 0){ throw new IllegalArgumentException("Negative balance"); } this.balance = balance; } public int getId(){ return this.id; } // To sort a collection of Accounts. public int compareTo(Account other){ return (id < other.getId() ? -1 : (id == other.getId() ? 0 : 1)); } } public class BankingSystem { protected List<Account> accounts; protected ReadWriteLock lock = new ReentrantReadWriteLock(); // !! public boolean transfer(Account from, Account to, int amount){ if(from.getId() != to.getId()){ synchronized(from){ if(from.getBalance() < amount) return false; lock.readLock().lock(); // !! from.setBalance(from.getBalance() - amount); } synchronized(to){ to.setBalance(to.getBalance() + amount); lock.readLock().unlock(); // !! } } return true; } // Rest of class.. }
Note that this is without even using the summation method yet, so no writeLock
is ever being aquired. If I only delet the lines marked with a // !!
and also do not call the summation method, suddenly the "transfer throughput" using multiple threads is a lot higher than when using a single thread, as is the goal.
My question now is, why does that simple introduction of a readWriteLock
slow down the entire thing that much, if I never try to aquire a writeLock
, and what I did wrong here, because I can't manage to find the problem.
- Sidenote: I had asked a question regarding this problem already here, but managed to ask the wrong question. I did however, get an amazing answer for that question I asked. I decided to not reduce question quality immensly, and to keep that great answer alive for people in need for help regardin that matter, I would not edit the question (yet again). Instead I opened this question, in the strong belief that this is NOT a duplicate, but instead an entirely different matter.