3

如何通过等待/通知持有多个锁?

想象一下有两个可锁定资源的情况:打印机和扫描仪。我遇到了死锁,所以我决定在打印机锁之前获取扫描仪锁。现在,如果我只想要打印机,我仍然需要锁定扫描仪。这里的情况是一个(打印)线程到达打印机,它注意到另一个(进纸)线程需要进纸。我的设计要求打印线程等待进纸线程进纸。

如果我在打印机上等待。我想我仍在锁定扫描仪。线程 2 怎么会输入通知代码?

在这种情况下常用的设计是什么?假设我需要持有 2 个锁(以避免死锁)。如何在两个锁都持有的情况下等待/通知?示例代码如下。

一种明显的方法是在整个代码中反转锁定获取顺序,并希望我不需要在扫描仪上等待。

还有其他出路吗?

示例代码:打印线程:

    synchronized (scanner) {
        synchronized (printer) {
            // action
            while (trayEmpty) {
                printer.wait();
            }
        }
    }

进线示例代码:

    synchronized (scanner) {
        synchronized (printer) {
            // action
            trayEmpty=false;
            printer.notify();
        }
    }
4

2 回答 2

1
Is there another way out?

我建议您不要使用等待/通知,而是使用Java Concurrent Api 显式锁lock,您可以unlock按顺序使用

于 2012-07-23T18:15:45.617 回答
0

这种特定情况的一个想法是使用单个锁。例如,在位于 row/col 交叉点的对象上创建一个锁定对象(例如,创建一个锁定对象矩阵)。

于 2012-07-23T18:12:03.483 回答