Android 已同步(锁){lock.notify();}中引发了IllegalMonitorStateException。。。为什么?

Android 已同步(锁){lock.notify();}中引发了IllegalMonitorStateException。。。为什么?,android,exception,locking,notify,Android,Exception,Locking,Notify,我正在调试一个由我们以前的一位开发人员编写的Android服务,他以以下方式使用了Boolean: public static class DownloadQueue extends LinkedHashMap { // ... private Boolean lock = new Boolean(false); // ... //typical notify use synchronized public Object addToHead(Obje

我正在调试一个由我们以前的一位开发人员编写的Android服务,他以以下方式使用了
Boolean

public static class DownloadQueue extends LinkedHashMap  
{
    // ...
    private Boolean lock = new Boolean(false);
    // ...

    //typical notify use
    synchronized public Object addToHead(Object key, Object value)
    {
        // ...
        synchronized (lock) 
        {
            //IllegalMonitorStateException FROM HERE
            lock.notify();
        }
        // ...
        return null;
    }

    //queue machinery
    public DownloadRecord getFirst()
    {
        // we block because queue is empty
        if(this.size() == 0 || (MyApp.isInternetConnectionAvailable() == false))
        {
            try 
            {   
                lock = true;
                synchronized (lock) 
                {
                    lock.wait(30000);
                }
                lock = false;
            }
            catch (InterruptedException e) 
            {}
        //continue operating the queue
        // ...
        return value;
    }
}
我在
IllegalMonitorStateException
上找到的文档表明,这是由于没有从
synchronized
块调用
notify()
引起的;然而,这里的情况显然不是这样。我确实想知道
lock
的范围是否有问题,或者不同步的分配是否有问题。所有对
lock
的引用都是上面的形式,队列函数中只有一个
wait(long)

最后一个可能有用的细节:这是因为,尽管我们的设备有网络,但我们的CMS已经关闭。我们正借此机会在这种情况下测试应用程序。我怀疑队列可能正在以惊人的速度运行,因为失败的下载正在重新排队,因此,如果竞争条件可能是导致此故障的原因,那么它可能就是这里的原因


谢谢

您对lock变量的同步不起作用,因为您一直在重新分配它:执行此操作时
lock=true
lock=false您正在更改“锁定”所指的对象。因此,当您在
addToHead
方法中获得一个锁,然后另一个线程调用getFirst时,锁的引用在它下面被更改,因此在您调用notify时它指向其他对象。

您对锁变量的同步不起作用,因为您一直在重新分配它:当您这样做时
lock=true
lock=false您正在更改“锁定”所指的对象。因此,当您在
addToHead
方法中获得一个锁,然后另一个线程调用getFirst,lock的引用在其下方发生了更改,因此在调用notify时它指向其他对象。

问题在于,您在
getFirst
方法中重新分配
lock
成员变量的值

Boolean是一种不可变类型,因此当您重新分配其值时,您正在创建一个新对象

这意味着您不能保证通知同步的同一对象(如果其间发生了重新分配)


最好将锁变量声明为
final
,以避免此类编程错误。

问题在于,您在
getFirst
方法中重新指定了
lock
成员变量的值

Boolean是一种不可变类型,因此当您重新分配其值时,您正在创建一个新对象

这意味着您不能保证通知同步的同一对象(如果其间发生了重新分配)


将锁变量声明为
final
是一种很好的做法,以避免此类编程错误。

谢谢!这看起来像是我的解决方案:)我另外确定了
lock
的值永远不会被读取,所以我删除了写入操作。谢谢!这看起来像是我的解决方案:)我另外确定了
lock
的值永远不会被读取,所以我删除了写入操作。