Java 回调中的notify()未发出wait()信号

Java 回调中的notify()未发出wait()信号,java,android,callback,thread-synchronization,Java,Android,Callback,Thread Synchronization,问题很简单。在Android上,我有一个需要调用库函数的方法。这个电话将发出我必须处理的回调信号。在我从我的方法返回之前,我必须等待回调被通知 我认为监视器对象上的wait()和notify()方法可以实现这一点。事实并非如此 基本上,监视对象被称为Connection,我在调用方法中实例化了它。然后,该方法执行一个循环,在该循环中调用Android库方法来“注销”对象。不幸的是,这个方法的响应是在一些回调中给出的。因此,我使用Connection.wait(10000)方法等待回调,在回调中,

问题很简单。在Android上,我有一个需要调用库函数的方法。这个电话将发出我必须处理的回调信号。在我从我的方法返回之前,我必须等待回调被通知

我认为监视器对象上的wait()和notify()方法可以实现这一点。事实并非如此

基本上,监视对象被称为
Connection
,我在调用方法中实例化了它。然后,该方法执行一个循环,在该循环中调用Android库方法来“注销”对象。不幸的是,这个方法的响应是在一些回调中给出的。因此,我使用
Connection.wait(10000)
方法等待回调,在回调中,我使用
Connection.notify()
在回调完成时发出信号(当然,所有回调都是同步的)。但是,
connection.notify()
不会释放
连接。等待(10000)
。我可以从Android logcat中看到注销成功,但在尝试下一个注销任务之前,我总是要等待10秒

下面是调用方法和回调的代码。我在推理中做出了什么愚蠢的假设,认为这是失败的。据我所知,调用方法(线程)肯定拥有监控对象,并将其交给
连接上的回调。等待(10000)

也许我对这个问题使用了一种完全不正确的方法?(我想要的是在所有注销完成之前阻止调用方的方法。)

回调如下所示,它与上述方法位于同一个类中,但它是Android中非常流行的“onSomeEvent()”之一:

    public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration btAppConfig, int status)
    {
        if (status == BluetoothHealth.APP_CONFIG_UNREGISTRATION_FAILURE)
        {
            Log.i(TAG, "Un-Registration of the Bluetooth Health Application failed");
            if(connection.useNotify() == true)
            {
                synchronized (connection)
                {
                    Log.i(TAG, "Signal unregistration failure");
                    // just indicate signaled
                    connection.setConnectionState(true);
                    connection.notify();
                }
            }
        }
        else if(status == BluetoothHealth.APP_CONFIG_UNREGISTRATION_SUCCESS)
        {
            Log.i(TAG, "Un-Registration of the Bluetooth Health Application successful");
            if(connection.useNotify() == true)
            {
                synchronized (connection)
                {
                    Log.i(TAG, "Signal unregistration success");
                    connection.setConnectionState(true);
                    connection.notify();
                }
            }
        }
    }

这段代码可能有很多错误:assylias得到了大部分错误。很明显,您肯定需要使用notifyAll,而不是notify。notify重新启动等待锁的线程;notifyAll重新启动它们

useNotify和setConnectionState也需要同步。此外,您还需要确保锁定的连接实例在这两个部分中是相同的,并且与调用notify的连接实例相同。最后,您需要保证通知调用实际上发生在等待调用之后


就方法而言,每当您使用这种低级工具时,您都应该怀疑是否有更好的方法。有几个更高层次的构造可以更简单地实现这一点。我建议您尝试重新设计代码,这样就不会等待回调。进行调用,将状态停在某个位置,然后在回调发生时处理它。

我想
连接。useNotify()/setNotify()
使用布尔字段-该字段是如何声明的?它是挥发性的吗?另外:您应该始终在循环中调用
wait
,除非您确定只有一个线程在等待,否则您应该使用
notifyAll
。如果您使用高级并发API(例如倒计时锁存器),而不是使用wait/notify,您的生活会更简单。是的。这些只是帮助您确定等待(10000)是否由于超时或notify()完成了任务而返回。因为wait()不返回任何内容,所以没有其他方法可以判断。最后,问题是调用方法每次尝试都要等待10秒。您能在日志猫中看到“信号注销失败”或“信号注销成功”吗?是的,我能看到它们。这部分工作正常。同时,我正在研究倒计时锁,因为这似乎是一种更好的方式来执行我在许多地方需要的任务。我只希望我能把它放进Android库调用的回调中,而不是我的代码!在这种情况下,我无法消除回调。它是图书馆的一部分,我必须等到它完成(最好不要睡觉)。正如您在这段代码中看到的,我已经成功地使用了wait/notify,但成功案例中的wait()是在被调用方法创建的自己的线程中启动的。当然,这并没有阻止创建线程的方法。从logcat消息可以清楚地看出,除了wait()的释放之外,一切都在按预期进行。我确信你是正确的,因为某些原因,连接对象不属于调用方。@Brian:不建议你取消回调!只是不要用“等待”来等待。相反,把你的州停在某个地方,做其他事情,当回调发生时,把它捡起来。我建议记录等待、同步和通知的对象的id。我打赌他们不是同一个物体。祝你好运谢谢你,布莱克。使用倒计时闩锁非常简单,我正在放弃等待/通知。我仍然想最终找出我做错了什么。。。时间允许的时候。
    public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration btAppConfig, int status)
    {
        if (status == BluetoothHealth.APP_CONFIG_UNREGISTRATION_FAILURE)
        {
            Log.i(TAG, "Un-Registration of the Bluetooth Health Application failed");
            if(connection.useNotify() == true)
            {
                synchronized (connection)
                {
                    Log.i(TAG, "Signal unregistration failure");
                    // just indicate signaled
                    connection.setConnectionState(true);
                    connection.notify();
                }
            }
        }
        else if(status == BluetoothHealth.APP_CONFIG_UNREGISTRATION_SUCCESS)
        {
            Log.i(TAG, "Un-Registration of the Bluetooth Health Application successful");
            if(connection.useNotify() == true)
            {
                synchronized (connection)
                {
                    Log.i(TAG, "Signal unregistration success");
                    connection.setConnectionState(true);
                    connection.notify();
                }
            }
        }
    }