我有两种方法(在C#中):
List<Pizza> CookPizza(List<Order>);
List<HappyCustomers> DeliverPizza(List<Pizza>);
这些操作没有共同的对象(除了从一个传递到另一个的比萨),并且是线程安全的。它们每个都需要几秒钟才能执行,它们每个都使用不同的资源(烤箱与汽车)。因此,我想同时运行它们。
如何使用这些约束来组织线程:
我一开始就知道所有的订单(比方说,我有10万个订单)。一个订单可以包含多个比萨饼,我不知道在比萨饼煮熟之前,任何订单中都有多少比萨饼。 (我知道很奇怪)。一般来说,订单有1个披萨,但最多可以有10个。
活跃的比萨饼的数量一般不应超过100.这包括新鲜煮熟的比萨饼和送达的比萨饼。这是一个软限制,所以我可以超过一些(例如,当一个大订单煮熟时)。硬限制可能接近500。
当他们获得大量工作时,这两项操作都会更有效率。通常,CookPizza在给出至少20个订单时效率最高。如果给予至少50个比萨饼,提供比萨饼是最有效的。也就是说,如果我给这些方法的项目少于那些数量,我会看到性能下降。如果只剩下这些物品,可以使用更少的物品。
我正在解决的主要问题是这些方法可能需要相互等待。
答案 0 :(得分:4)
你想要一个并发缓冲区 - 可能是并发队列,你可能需要几个。您想要一个并发的订单队列。您使用并发队列调用CookOrder。当CookOrder返回时,您将使用队列的新内容再次调用它。在这里,您只能发布前100个项目或其他内容。这里的订单有效地由队列批处理,CookOrder始终在运行。然后你再用Pizzas重复这个过程。
答案 1 :(得分:4)
我首先使用基于事件的模型来解决这个问题。
假设我们有一个PizzaDispatcher
对象给出了订单。调度程序开始使用初始空状态的设定数量的订单调用CookPizza
。当比萨饼煮熟时,CookPizza
功能会通知调度员披萨已经煮熟(可能是通过您提供的回调作为参数)。当披萨发送时,DeliverPizza
功能也会这样做。
PizzaDispatcher
现在有足够的信息可以根据煮熟的比萨饼数量和未完成的送货量来决定何时以及有多少比萨饼用于烹饪或送餐。
这可以重构为使用事件而不是回调等,但我是为了这个想法发布它,而不是实现的具体细节。
答案 2 :(得分:1)
您似乎只需要PizzaManager
决定首先烹饪的Pizza
订单,然后将它们传递给DeliveryBoy
以便传递它们。然后,在DeliveryBoy
DeliversPizza
后,他会向PizzaManager
报告,以检索下一个Pizza
订单。 PizzaManager
负责处理与优化订单烹饪和交付优先级相关的所有数学计算。 DeliveryBoy
可能会将PizzaManager
作为delegate
。
答案 3 :(得分:0)
一个想法
将一个成员变量添加到Pizza以跟踪is_cooked。 然后在CookPizza中,完成后将该成员设置为true, 然后在DeliverPizza期间,在继续之前检查该成员。