如何保证Java中2个顺序语句的线程安全?

时间:2019-01-07 01:52:47

标签: java multithreading transactions locking conditional-statements

此模拟的银行帐户转帐功能如下,使用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();
        }
    }

看起来不错,因为这是使用线程同步条件的常见示例,因此在线程中断时,锁定将始终为“解锁”。

但如果此线程在它们之间的位置被中断

accounts[from] -= amount;//risky

accounts[to] += amount;  //risky

然后,银行总金额将完全不是余额!而且我认为将“帐户”声明为原子数组并不能解决问题。我认为问题在于,我应该在交易中赚“ +钱”和“-钱”,要么成功要么回退。

那么在Java并发库中有什么便捷的方法可以实现这种“交易”?还是需要一些特殊的设计,以及如何实现?

非常感谢。

1 个答案:

答案 0 :(得分:2)

胎面不会在随机点发生中断。

如果有人调用Thread.interrupt,它不会立即停止线程。

ThreadInterruptException仅从声明它的方法中引发。

因此,如果您不从代码中调用任何此类方法,就不会有问题。