我有一个Thread
,称它为WorkerThread
,它的工作是让一个给定的对象SomeObject
,周期性地做一些工作。
SomeObject
关注通过套接字进行一些通信。它必须做的一些工作是在专用于套接字 I/O 的另一个线程上执行的。调用那个 CommsThread
。我认为 CommsThread
是 SomeObject
的内部实现。
当 SomeObject
忙于工作时,WorkerThread
将在监视器对象上 wait()
。当 SomeObject
发生异步回调时,notify()
将在回调处理程序中调用,然后 Thread A
将继续其愉快的方式。
这以前有效——但只是因为 Object A
恰好在 CommsThread
的上下文中执行其异步回调,这意味着 notify()
可以在监视器对象上调用,允许 WorkerThread
唤醒并继续。
我一直在重构一些东西,并意识到我认为我的类在线程上异步回调而不是在它们被实例化的线程上,或者那些回调发生在“内部”上是非常糟糕的设计线。回调以前发生在 CommsThread
的上下文中。因此,在 SomeObject
中,我使用了 Android Handler
来使异步回调发生在实例化 SomeObject
的线程上。我相信,这是更好的设计。但这现在会导致有关 WorkerThread
的死锁情况。当然 WorkerThread
现在无限期地坐在 wait()
中。
这让我想到了两个相关的问题:
如果我正在设计一个具有异步回调的类或接口(interface),回调发生在创建对象的线程或 UI 线程上是约定俗成还是一般来说是一件好事?
假设我根据上述设计我的类并且异步回调不会发生在单独的线程上,
WorkerThread
应该如何有效地等待这样的回调?我想到的一种解决方法是在创建WorkerThread
之前在 UI 线程上实例化SomeObject
,然后将其传递到线程中。异步回调将在 UI 线程的上下文中发生,因此wait()
/notify()
将起作用。
最佳答案
第三种解决方案是完全放弃使用陈旧的 wait/notify
机制并使用真正的并发结构。
我建议您仔细研究您的要求,并考虑使用 BlockingQueue
进行线程间通信,或者可能一些谨慎的 Lock
用法。
如果您可以扩展您的实际需求,而不是假设回调是正确的方法,我相信我们可以提供更多帮助。
目前对回调的态度是它们几乎总是一种气味。但是,有一些看起来很像回调的模式被认为是可以接受的。
关于java - 等待异步回调的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25613065/