0

There is such synchronized function:

private int balance;


//...

public synchronized void executeRequest(Request request) {

        switch (request.getType()) {
            case CREDIT:
                if(balance >= request.getAmount()) {
                    balance -= request.getAmount();
                    System.out.printf(SUCCESS,
                            request,
                            Thread.currentThread().getName(),
                            balance);
                } else {
                    System.out.printf(FAILURE,
                                    request,
                                    Thread.currentThread().getName(),
                                    balance);
                }

                break;
            case REPAYMENT:
                balance += request.getAmount();
                System.out.printf(SUCCESS,
                        request,
                        Thread.currentThread().getName(),
                        balance);
                break;

        }
    }

I need to rewrite it by using AtomicInteger for balance parameter.

I can't come up with how to do two actions atomically:

  1. balance >= request.getAmount()
  2. balance -= request.getAmount();

I try to rewrite CREDIT operation like that:

private void credit(int amount, String request) {
        int oldValue;
        int newValue;
        do {
            oldValue = balance.get();
            newValue = oldValue - amount;
            if (oldValue >= amount) {
                System.out.printf(SUCCESS,
                        request,
                        Thread.currentThread().getName(),
                        balance);
            } else {
                System.out.printf(FAILURE,
                        request,
                        Thread.currentThread().getName(),
                        balance);
            }
        } while (!balance.compareAndSet(oldValue, newValue));
    }

But it won't work, because there's no guarantee that oldValue >= amount will be true when we try to compute !balance.compareAndSet(oldValue, newValue) again.

Have you any idea how to rewrite the first method with AtomicInteger?

  • I don't understand your concern. The code looks fine to me, except that when `balance < amount` it will print failure but then go ahead and deduct `amount` anyway, leaving a negative balance. It's not clear if that's what you intend. – Nate Eldredge Jul 08 '21 at 15:19

1 Answers1

0

I came up with a such decision. What do you think about it?

private void credit(int amount, String request) {
        int oldValue;
        int newValue;
        while (true) {
            oldValue = balance.get();
            newValue = oldValue - amount;
            if (oldValue >= amount && balance.compareAndSet(oldValue, newValue)) {
                System.out.printf(SUCCESS,
                        request,
                        Thread.currentThread().getName(),
                        newValue);
                break;
            } else if (oldValue < amount) {
                System.out.printf(FAILURE,
                        request,
                        Thread.currentThread().getName(),
                        oldValue);
                break;
            }
        }
    }