在 notifyAll() 之前没有被线程锁定的同步对象 [英] synchronized object not locked by thread before notifyAll()

查看:29
本文介绍了在 notifyAll() 之前没有被线程锁定的同步对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要一个布尔值来通知系统的某些部分特定服务已启动.

I want to have a boolean to notify some sections of the system that a specific service started.

由于某些奇怪的原因,我收到错误 java.lang.IllegalMonitorStateException: object not locked by thread before notifyAll().

For some strange reason I'm getting the error java.lang.IllegalMonitorStateException: object not locked by thread before notifyAll().

奇怪的是 notifyAll() 位于一个同步块中,该块控制我调用 notifyAll() 的对象.

What is strange is that the notifyAll() is inside a synchronized block that takes control over the object that I call notifyAll() on.

我的课是这样开始的:

public class MyService {

    public static Boolean notifier = Boolean.valueOf(false);

    @Override
    public void start() {
        synchronized (MyService.notifier) {
            MyService.notifier = Boolean.valueOf(true);
            MyService.notifier.notifyAll();
        }
    }

    @Override
    public void stop() {
        synchronized (MyService.notifier) {
            MyService.notifier = Boolean.valueOf(false);
            MyService.notifier.notifyAll();
        }
    }
    ...
}

我正在开发一个安卓应用程序.我认为它不会影响任何事情,但我会用该评论补充问题,以防影响 java 的工作方式.

I'm working on an android application. I don't think it should affect anything, but I'm complementing the question with that comment in case that affects the way that java works.

如果对象被锁定在同步块中,为什么会出现异常?

Why am I getting the exception if the object is locked inside a synchronized block?

推荐答案

MyService.notifier = Boolean.valueOf(true);

交换你锁定的对象,它用对新对象的引用覆盖变量.因此,您在进入块时获得锁定的对象与您调用 notifyAll 的对象不同.notifyAll 所知道的是,它还没有获得被调用对象的锁,这是进入同步块后创建的新对象.

swaps out the object you're locking on, it overwrites the variable with a reference to a new object. So the object you acquired the lock on upon entering the block is not the same one that you're calling notifyAll on. All notifyAll knows is it hasn't acquired the lock on the object it's being called on, which is the new object created after the synchronize block was entered.

所有线程都需要使用同一个锁.就像 Ian Roberts 所说,锁属于对象.如果你覆盖了这个对象,你就有了一个新的锁.

All the threads need to be using the same lock. Like Ian Roberts said, the lock belongs to the object. If you overwrite the object you have a new lock.

这篇关于在 notifyAll() 之前没有被线程锁定的同步对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆