请帮忙一点。

我正在设计一个具有以下功能的无状态服务器:


客户端向服务器提交作业。
服务器尝试执行作业时,客户端被阻止。
服务器将产生一个或多个线程来执行作业。
作业完成,超时或失败。
创建适当的响应(基于结果),解除对客户端的阻止,并将响应移交给客户端。


到目前为止,这是我想到的。


客户端向服务器提交作业。
服务器为该作业分配一个ID,将其放置在队列中,然后将客户端放置在另一个队列中(该队列将被阻止)。
有一个将执行作业,获取结果并适当创建响应的线程池。
根据ID,从队列中选择客户端(从而取消对其进行阻塞),向其提供响应并发送出去。


步骤1、3、4似乎很简单,但是关于如何将客户端放入队列然后阻止它的任何想法。另外,任何能帮助我设计这只小狗的指针将不胜感激。

干杯

最佳答案

为什么需要阻止客户?似乎更容易立即返回(几乎)(在执行初始验证后,如果有的话)并为客户提供给定作业的唯一ID。然后,客户将能够使用所述ID进行轮询,或者提供回调。

阻止意味着您要坚持使用套接字,这显然限制了您可以同时服务的最大客户端数量。如果这不是您所关心的情况,并且您绝对需要阻止(也许您无法控制客户端代码并且无法对它们进行轮询?),那么除非您可以将其实际拆分为多个对象,否则生成线程来执行该工作几乎没有任何意义。并行任务。在这种情况下,唯一的“队列”将是公共线程池所拥有的队列。工作流程基本上是:


创建一个线程池(例如ThreadPoolExecutor
对于每个客户请求:


如果您可以并行执行作业的任何部分,请将它们委派给池。
和/或在当前线程中执行它们。
等待直到合并的作业部分完成(如果适用)。
将结果返回给客户。

关闭线程池。


本身不需要ID。尽管您可能需要对上述2.1 / 2.3使用某种latch

超时可能有点棘手。如果您需要提高它们的精确度,则必须使您的主线程(接收到客户请求的那个主线程)从工作中释放出来,并在达到超时时使其信号通知已提交的工作部分(通过翻转标志)并立即返回。您必须定期检查所述标志,并在翻转后终止执行。然后池将回收该线程。

09-04 18:38
查看更多