我正在设计一个包含三个部分的应用程序:
- 监视某些事件(文件创建,外部请求等)发生的单个线程
- N个工作线程通过处理它们来响应这些事件(每个工作进程处理并消耗一个事件,并且处理可能需要花费可变的时间)
- 一个控制器,用于管理那些线程并执行错误处理(线程重新启动,结果记录)
尽管这是非常基本的,并且不难实现,但我想知道这样做的“正确”方法是什么(在Java的这种具体情况下,但也希望有更高的抽象答案)。我想到两种策略:
观察者/可观察者:监视线程由控制器观察。在发生事件的情况下,然后会通知控制器,并可以将新任务分配给可重用的缓存线程池中的空闲线程(如果所有线程当前都忙,请等待并将任务缓存在FIFO队列中)。工作线程实现Callable并返回结果(或布尔值)成功或返回错误,在这种情况下,控制器可以决定要执行的操作(取决于发生的错误的性质)。
生产者/消费者:监视线程与控制器(事件队列)共享一个BlockingQueue,并且控制器与所有工作器(任务队列和结果队列)共享两个。在发生事件的情况下,监视线程将任务对象放入事件队列中。控制器从事件队列中获取新任务,对其进行审阅并将其放入任务队列中。每个工作人员都在等待新任务,并从任务队列中获取/使用它们(先到先服务,由队列本身进行管理),然后将结果或错误放回到结果队列中。最后,控制器可以从结果队列中检索结果,并在出现错误的情况下采取相应的步骤。
两种方法的最终结果是相似的,但是它们都有细微的差别:
使用观察者,线程的控制是直接的,每个任务都归属于特定的新生成的工作程序。创建线程的开销可能更高,但是由于缓存了线程池,因此开销并不大。另一方面,“观察者”模式被简化为单个“观察者”模式,而不是多个观察者模式,这与其设计的目的不完全相同。
队列策略似乎更容易扩展,例如,添加多个生产者而不是一个生产者很简单,不需要任何更改。不利之处在于,即使根本不做任何工作,所有线程也将无限期运行,并且错误/结果处理看起来不像第一个解决方案那样优雅。
在这种情况下最合适的方法是什么?为什么?我发现很难在线找到该问题的答案,因为大多数示例仅处理明确的案例,例如用“观察者”案例更新许多具有新值的窗口或与多个消费者和生产者进行处理。任何输入,不胜感激。