我看到的核心问题是 (a) 避免死锁和 (b) 在线程之间交换数据。出租人的一个担忧(但只是轻微出租人)是避免瓶颈。我已经遇到过几个不同的乱序锁导致死锁的问题——说“总是以相同的顺序获取锁”很好,但在中型到大型系统中,实际上通常不可能确保这一点。
警告:当我想出这个解决方案时,我必须以 Java 1.1 为目标(所以并发包在 Doug Lea 眼中还不是一闪而过)——手头的工具完全同步并等待/通知。我借鉴了使用基于实时消息的系统 QNX 编写复杂的多进程通信系统的经验。
根据我使用 QNX 的经验,它存在死锁问题,但通过将消息从一个进程的内存空间处理到另一个进程来避免数据并发,我提出了一种基于消息的对象方法 - 我称之为 IOC,用于交互- 对象协调。一开始我设想我可能会像这样创建所有我的对象,但事后看来,它们只在大型应用程序的主要控制点是必要的 - “州际交换”,如果你will,不适用于道路系统中的每个“交叉口”。事实证明这是一个主要的好处,因为它们完全不是 POJO。
我设想了一个系统,其中对象在概念上不会调用同步方法,而是“发送消息”。消息可以是发送/回复的,发送者在消息被处理时等待并返回回复,或者是异步的,消息被放到队列中并在稍后阶段出列和处理。请注意,这是概念上的区别 - 消息传递是使用同步方法调用实现的。
消息系统的核心对象是IsolatedObject、IocBinding 和IocTarget。
IsolatedObject 之所以这样称呼是因为它没有公共方法;这是为了接收和处理消息而扩展的。使用反射进一步强制子对象没有公共方法,也没有任何包或受保护的方法,除了那些从 IsolatedObject 继承的方法,几乎所有这些方法都是最终的;一开始看起来很奇怪,因为当你继承IsolatedObject时,你创建了一个带有1个受保护方法的对象:
Object processIocMessage(Object msgsdr, int msgidn, Object msgdta)
其余所有方法都是处理特定消息的私有方法。
IocTarget 是一种抽象隔离对象可见性的方法,对于为另一个对象提供自引用以将信号发回给您非常有用,而不会暴露您的实际对象引用。
并且 IocBinding 只是将发送者对象绑定到消息接收者,这样就不会对发送的每条消息进行验证检查,而是使用 IocTarget 创建的。
与隔离对象的所有交互都是通过“发送”消息来实现的——接收者的 processIocMessage 方法是同步的,从而确保一次只处理一条消息。
Object iocMessage(int mid, Object dta)
void iocSignal (int mid, Object dta)
创建了这样一种情况,即隔离对象完成的所有工作都通过一个方法集中起来,接下来我通过它们在构造时声明的“分类”将对象排列在声明的层次结构中 - 只是一个将它们标识为的字符串是任意数量的“消息接收器类型”之一,它将对象置于某个预定的层次结构中。然后我使用消息传递代码来确保如果发送者本身是一个独立对象,对于同步发送/回复消息,它是层次结构中较低的对象。异步消息(信号)使用线程池中的单独线程分派给消息接收者,线程池的整个工作传递信号,因此信号可以从任何对象发送到系统中的任何接收者。信号可以传递任何所需的消息数据,但不能回复。
因为消息只能在向上方向传递(并且信号总是向上传递,因为它们是由专门为此目的运行的单独线程传递的)死锁被设计消除了。
由于线程之间的交互是通过使用 Java 同步交换消息来完成的,因此设计上同样消除了竞争条件和陈旧数据问题。
因为任何给定的接收器一次只处理一条消息,并且因为它没有其他入口点,所以消除了对对象状态的所有考虑 - 实际上,对象是完全同步的,并且不会意外地忽略任何方法;没有 getter 返回陈旧的缓存线程数据,也没有 setter 在另一个方法作用于它时更改对象状态。
由于只有主要组件之间的交互通过这种机制进行汇集,因此在实践中,这已经很好地扩展了 - 这些交互在实践中并不像我所推测的那样经常发生。
整个设计成为子系统的有序集合之一,以严格控制的方式进行交互。
请注意,这不适用于更简单的情况,即使用更传统的线程池的工作线程就足够了(尽管我经常通过发送 IOC 消息将工作线程的结果注入主系统)。它也不用于线程关闭并执行完全独立于系统其余部分的事情的情况,例如 HTTP 服务器线程。最后,它不用于资源协调器本身不与其他对象交互以及内部同步将完成工作而没有死锁风险的情况。
编辑:我应该声明交换的消息通常应该是不可变的对象;如果使用可变对象,则发送它的行为应被视为移交并导致发送者放弃所有控制权,并且最好不保留对数据的引用。就个人而言,我使用了一个可锁定的数据结构,它被 IOC 代码锁定,因此在发送时变得不可变(锁定标志是易失的)。