我有一个多线程布局,其中有一个管理器对象和很多工作对象。
我怀疑哪种布局更好用:
1 - 工人们在一个循环中奔跑并向经理要求“新工作” 完成后不断。
或
2 - 经理在完成每项工作后为工人提供新工作 工作
对此有什么建议吗?
答案 0 :(得分:1)
他们原则上并没有那么不同。我认为这实际上取决于你如何实现逻辑来做这些事情。我可以看出,与你结束的方式相比,它会产生更大的不同。
关键的两个部分2虽然是经理需要知道工人是否完成了工作。所以在这一点上,工人仍然需要告诉经理,这与要求新工作几乎相同。
我认为这真的取决于你打算如何做IPC。从理论上讲,我认为第二个是更好的选择,但这取决于你如何优雅地使它发挥作用。
答案 1 :(得分:1)
这是我多次摔跤的问题。每次我选择我正在编码的具体情况。你也应该这样做。
但是,要正确选择,您必须仔细研究这两种方法。
考虑一个测试用例。
您需要处理数千个文件。
manager
成为要处理的所有文件的队列。您创建固定数量的worker
个线程,从管理器请求下一个文件并重复,直到列表用完为止。
您通常最终必须synchronize
访问队列。
您可以修改工作者数量,以获得硬件架构的最大吞吐量。
有时您可以根据当前负载动态调整工作人员数量,但这可能很棘手。如果成功,您通常可以获得特别优化的解决方案。
manager
为每个文件创建一个新的Callable
,并将其添加到Executor
受控线程池中。
嗯......如果你想一想就差不多了。唯一的区别是执行者排队。
需要较少的同步(当然除了Executor
内部)。
动态调整线程数并非易事,但我希望可以将Executor
子类化为实现此目的。
总结
这两种架构几乎相同。许多线程并行处理一系列项目。
差异在于动态和足迹。
当工人处于控制之下时,任何时候都存在已知数量的物体。可以建立一个广泛的队列,但这些可能是小对象。工作以固定且可预测的速度完成。如果工作开始堆积,你必须特别努力处理它。
当经理处于控制之中时,可能会爆发工人,其中大多数人只是坐在那里等待执行人。实质上,执行者成为管理者,线程池保存工作者。
我个人更喜欢工人控制。大多数情况下,我认为因为给定两个基本相似的架构,我通常更喜欢具有最可预测足迹的架构。我打算做实验。
答案 2 :(得分:0)
我会使用BlockingQueue
。管理器在循环中将作业添加到队列中,并且工作程序从队列中获取作业并在循环中执行它们。