Hind Forsum
Hind Forsum

Reputation: 10527

How to guarantee thread safe for 2 sequential statements in java?

This simulated bank account transfer functions like below, using ReentrantLock.newCondition():

class Bank {
    private Lock bankLock = new ReentrantLock();
    private Condition sufficientFunds = bankLock.newCondition();
    private final double[] accounts;

    public Bank(int n, double initialBalance) {
        accounts = new double[n];
        Arrays.fill(accounts, initialBalance);
    }

    public void transfer(int from, int to, double amount) throws InterruptedException {
        bankLock.lock();
        try {
            while(accounts[from] < amount) {
                sufficientFunds.await();
            }
            System.out.println(Thread.currentThread());
            accounts[from] -= amount;//risky
            // What if interrupted here ??????
            accounts[to] += amount;  //risky
            sufficientFunds.signalAll();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            bankLock.unlock();
        }
    }

It looks OK, because this is the usual sample of using condition for thread synchronization, the lock will always be "unlocked" when thread interrupted.

But in case this thread is interrupted in the places between

accounts[from] -= amount;//risky

and

accounts[to] += amount;  //risky

Then the total bank amount will not be balances at all! And I think declaring "accounts" to be atomic array doesn't solve the problem. I think the problem lies in that, I should make "+ money" and "- money" inside a transaction, either both success, or should rollback.

So it there any convenient way in java concurrent library to achieve this "transaction" ? Or this needs some special design, and how to implement it?

Thanks a lot.

Upvotes: 0

Views: 78

Answers (1)

talex
talex

Reputation: 20544

Interruption of tread can't happen at random point.

If someone call Thread.interrupt it doesn't stop thread immediately.

ThreadInterruptException will be raised only from methods that declare it.

So if you don't call any such method from your code there is no problem.

Upvotes: 2

Related Questions