【问题标题】:IllegalMonitorStateException thrown in synchronized(lock){lock.notify();} ... why?在 synchronized(lock){lock.notify();} 中抛出 IllegalMonitorStateException ... 为什么?
【发布时间】:2011-12-05 16:00:35
【问题描述】:

我正在调试我们以前的一位开发人员编写的 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 已关闭。我们借此机会在这种情况下测试应用程序。我怀疑队列可能正在以极快的速度运行,因为失败的下载正在重新排队,所以如果争用条件可能是导致此故障的原因,那么它可能就是这里的原因。

谢谢!

【问题讨论】:

    标签: android exception locking notify


    【解决方案1】:

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

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

    这意味着您不能保证通知您同步的同一个对象(如果在两者之间发生重新分配)。

    最好将锁变量声明为final 以避免这种编程错误。

    【讨论】:

    • 谢谢!这对我来说似乎是解决方案:)
    • 我还确定lock 的值永远不会被读取,所以我删除了写入。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-17
      • 2013-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-03
      • 1970-01-01
      相关资源
      最近更新 更多