Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package fgbank;
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
- /**
- * Bank implementation.
- *
- * <p>:TODO: This implementation has to be made thread-safe.
- */
- public class BankImpl implements Bank {
- /**
- * An array of accounts by index.
- */
- private final Account[] accounts;
- /**
- * Creates new bank instance.
- * @param n the number of accounts (numbered from 0 to n-1).
- */
- public BankImpl(int n) {
- accounts = new Account[n];
- for (int i = 0; i < n; i++) {
- accounts[i] = new Account();
- }
- }
- /**
- * {@inheritDoc}
- */
- @Override
- public int getNumberOfAccounts() {
- return accounts.length;
- }
- /**
- * {@inheritDoc}
- * <p>:TODO: This method has to be made thread-safe.
- */
- @Override
- public long getAmount(int index) {
- long res = -1;
- accounts[index].lock.lock();
- res = accounts[index].amount;
- accounts[index].lock.unlock();
- return res;
- }
- /**
- * {@inheritDoc}
- * <p>:TODO: This method has to be made thread-safe.
- */
- @Override
- public long getTotalAmount() {
- long sum = 0;
- for (Account account : accounts) {
- account.lock.lock();
- }
- for (Account account : accounts) {
- sum += account.amount;
- }
- for (Account account : accounts) {
- account.lock.unlock();
- }
- return sum;
- }
- /**
- * {@inheritDoc}
- * <p>:TODO: This method has to be made thread-safe.
- */
- @Override
- public long deposit(int index, long amount) {
- try {
- accounts[index].lock.lock();
- if (amount <= 0) {
- throw new IllegalArgumentException("Invalid amount: " + amount);
- }
- if (amount > MAX_AMOUNT || accounts[index].amount + amount > MAX_AMOUNT) {
- throw new IllegalStateException("Overflow");
- }
- accounts[index].amount += amount;
- return accounts[index].amount;
- } catch (IllegalArgumentException | IllegalStateException ex) {
- throw ex;
- }
- finally {
- accounts[index].lock.unlock();
- }
- }
- /**
- * {@inheritDoc}
- * <p>:TODO: This method has to be made thread-safe.
- */
- @Override
- public long withdraw(int index, long amount) {
- try {
- accounts[index].lock.lock();
- if (amount <= 0) {
- throw new IllegalArgumentException("Invalid amount: " + amount);
- }
- if (accounts[index].amount - amount < 0) {
- throw new IllegalStateException("Underflow");
- }
- accounts[index].amount -= amount;
- return accounts[index].amount;
- } catch (IllegalArgumentException | IllegalStateException ex) {
- throw ex;
- } finally {
- accounts[index].lock.unlock();
- }
- }
- /**
- * {@inheritDoc}
- * <p>:TODO: This method has to be made thread-safe.
- */
- @Override
- public void transfer(int fromIndex, int toIndex, long amount) {
- int minInd = Math.min(fromIndex, toIndex);
- int maxInd = Math.max(fromIndex, toIndex);
- try {
- accounts[minInd].lock.lock();
- accounts[maxInd].lock.lock();
- if (amount <= 0) {
- throw new IllegalArgumentException("Invalid amount: " + amount);
- }
- if (fromIndex == toIndex) {
- throw new IllegalArgumentException("fromIndex == toIndex");
- }
- if (amount > accounts[fromIndex].amount) {
- throw new IllegalStateException("Underflow");
- }
- else if (amount > MAX_AMOUNT || accounts[toIndex].amount + amount > MAX_AMOUNT) {
- throw new IllegalStateException("Overflow");
- }
- accounts[fromIndex].amount -= amount;
- accounts[toIndex].amount += amount;
- } catch (IllegalArgumentException | IllegalStateException ex) {
- throw ex;
- } finally {
- accounts[minInd].lock.unlock();
- accounts[maxInd].lock.unlock();
- }
- }
- /**
- * Private account data structure.
- */
- private static class Account {
- /**
- * Amount of funds in this account.
- */
- long amount;
- Lock lock = new ReentrantLock();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement