我已经在Java中编写了一个实现双重缓冲区的类。
该类有两种写入两个缓冲区的方法和一种清除它们的方法。
然后,我有三个线程:一个线程在第一个缓冲区上写,另一个线程在第二个缓冲区上写,第三个在清除缓冲区上。

在这里,我粘贴导致问题的代码(一部分)(我知道这是不正确的,但出于调试目的已对其进行了简化):

public void addAlpha(int toAdd){
synchronized (alphaCount) {
    while(alphaCount >= alpha.length){
        try {
        alphaCount.wait();
        } catch (InterruptedException e) {
        }
    }

    alpha[alphaCount] = toAdd;
    alphaCount++;
    }
}

这是我调用notifyAll()的那一部分:
public void clear(){
    synchronized (alphaCount) {
        alphaCount = 0;
        alphaCount.notifyAll();
    }
}

如您所见,在addAlpha方法中,我获得了alphaCount的锁,测试了条件,然后等待alphaCount对象。

在clear方法中,我获得了alphaCount的锁,并在其上调用notifyAll()。
在运行时,我收到IllegalStateMonitorException ...

但是我真的不知道错误在哪里:我检查了文档并查看了多个论坛,但没有任何运气...

感谢您的时间和关注,
瑞克

最佳答案

通常,应将字段用作锁final,否则可能会遇到类似的错误。恕我直言,您应该尽可能多地填写决赛。 ;)

synchronized (alphaCount) { // alphaCount == 1 which is locked.
    alphaCount = 0;         // alphaCount == 0 which is not locked.
    alphaCount.notifyAll(); // fails.
}

另外,我不建议对锁使用Integer或String或任何包装器类型。由于存在许多令人困惑和令人惊讶的后果。例如
Integer i1 = 127;
Integer i2 = 127; // same object due to the auto-boxing cache.
i1 == i2;

Integer i1 = 128;
Integer i2 = 128; // not the same object.
i1 != i2; // may or may not be the same object depending on the cache size.

另一个问题是,使用完全不相关的库可能会出现死锁,该库也恰好使用整数作为锁。

解决方案是使用专用的锁定对象。
private final Object alphaCountLock = new Object();
private int alphaCount = 0; // don't use an object when a primitive will do.

synchronized (alphaCountLock ) {
    alphaCount = 0;
    alphaCountLock .notifyAll();
}

10-04 11:13