multithreading - 如何确保锁定顺序以避免死锁?

标签 multithreading locking deadlock

假设有以下 Account 类的两个对象 - account1 和 account2。并且有两个线程T1和T2。

T1 正在将金额 100 从 account1 转移到 account2,如下所示:

account1.transfer(account2, 100);

类似地,T2 正在将金额 50 从 account2 转移到 account1:
account2.transfer(account1, 50);

transfer() 方法显然容易发生死锁,因为两个线程 T1 和 T2 将尝试以相反的顺序获取锁。 (线程 T1 将首先尝试获取 account1 上的锁,然后再获取 account2 上的锁。而线程 T2 将尝试先获取 account2 上的锁,然后再获取 account1 上的锁。)

确保始终保证锁定顺序的最佳方法是什么(在这种情况下)?
public class Account {
    private float balance;

    public class Account() {
        balance = 5000f;
    }

    private void credit(float amt) {
        balance += amt;
    }

    // To exclude noise assume the balance will never be negative
    private void debit(float amt) {
        balance -= amt;
    }

    // Deadlock prone as the locking order is not guaranteed
    public void transfer(Account acc2, float amt) {
        synchronized(this) {
            synchronized(acc2) {
                acc2.debit(amt);
                this.credit(amt);
            }
        }
    }
}

最佳答案

我只会让一个线程访问“帐户”数据。任何其他想要转移资金的线程都必须向它排队一个“transferRequest”对象,其中包含帐户 ID、要转移的金额、异常/错误消息字段和回调/事件,以 transferRequest 作为参数,用于线程在尝试交易时调用。

然后传输被完整地序列化,唯一的锁在队列中,所以死锁是不可能的。

我讨厌多把锁,无论是否正确订购。

关于multithreading - 如何确保锁定顺序以避免死锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17268485/

相关文章:

python - 调用 pkill 以在 python 中的类中暂停具有子进程的进程会暂停 python 脚本

c# - 为什么我们这里没有死锁?

multithreading - 解决死锁: Lock Ordering

multithreading - 我正在做的事情可以防止死锁吗?

c - 锁定顺序或调度问题

c - C 中的多客户端服务器 - 哪种方法最适合这种特定情况?

multithreading - 如何共享包含文件句柄的对象?

java - 我怎样才能让我的构造函数同步?

Java 内存模型 : reordering and concurrent locks

java - Scala/Java 中的等价锁?