【问题标题】:How to guarantee thread safe for 2 sequential statements in java?java - 如何保证java中2条顺序语句的线程安全?
【发布时间】:2019-06-01 17:21:18
【问题描述】:

这个模拟的银行账户转账函数如下所示,使用 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并发库中有什么方便的方法来实现这个“事务”吗?或者这需要一些特殊的设计,如何实现?

非常感谢。

【问题讨论】:

标签: java multithreading transactions locking conditional-statements


【解决方案1】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 2016-01-03
    • 2017-04-27
    • 1970-01-01
    • 2021-12-18
    • 2013-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多