对三种不同并发模型的 Java 支持

我正在多线程环境中经历不同的并发模型(http://tutorials.jenkov.com/java-concurrency/concurrency-models.html)

本文重点介绍了三种并发模型

  1. 平行工作者

    第一个并发模型是我所说的并行工作线程模型。传入作业分配给不同的工作人员

  2. 装配线

    工人像工厂装配线上的工人一样组织起来。每个工作人员只执行全部作业的一部分。完成该部件后,工作人员将作业转发给下一个工作人员。

    每个工作线程都在自己的线程中运行,并且不与其他工作线程共享任何状态。这有时也称为无共享并发模型。

  3. 功能并行性

    函数并行性的基本思想是使用函数调用实现程序。函数可以看作是相互发送消息的“代理”或“参与者”,就像在装配线并发模型(AKA反应式或事件驱动系统)中一样。当一个函数调用另一个函数时,这类似于发送消息。

现在我想为这三个概念映射Java API支持

  1. Parallel Workers : Is it ExecutorServiceThreadPoolExecutorCountDownLatch API?

  2. 组装线:将事件发送到JMS等消息传递系统,并使用队列和主题的消息传递概念。

  3. 功能并行性一定程度上ForkJoinPool和java 8流。与流相比,ForkJoin池易于理解。

映射这些并发模型是否正确?如果没有,请纠正我。


答案 1

这些模型中的每一个都从一般的角度说明了如何完成/拆分工作,但是当涉及到实现时,这实际上取决于您的确切问题。一般来说,我是这样看的:

  1. 并行工作者:生产者在某个地方(例如在)上创建新作业,并且许多线程(通过)并行处理这些作业。当然,您也可以使用 ,但这意味着您希望在处理完子问题后触发操作(例如,您知道您的大问题可能被拆分为较小的问题,请查看此处的第二个示例)。BlockingQueueExecutorServiceCountDownLatchNN
  2. 装配线:对于每个中间步骤,您都有一个和一个或一个.在每一步中,作业都从一个步骤中取出,放入下一个步骤中,以进行进一步处理。对于您关于JMS的想法:JMS用于连接分布式组件,并且是Java EE的一部分,并且不被认为是在高并发上下文中使用的(消息通常在处理之前保存在硬盘上)。BlockingQueueThreadExecutorServiceBlickingQueue
  3. 功能并行性:这是一个很好的例子,说明如何实现这一点。ForkJoinPool

答案 2

一个很好的问题,答案可能不那么令人满意。列出的并发模型显示了您可能希望实现并发系统的一些方法。该 API 提供了用于实现任何这些模型的工具。

让我们从 ExecutorService 开始。它允许您提交要以非阻塞方式执行的任务。然后,ThreadPoolExecutor 实现会限制可用线程的最大数量。ExecutorService 不需要任务来执行完整的进程,就像您对并行工作线程的期望一样。该任务可以限制为流程的特定部分,并在完成后发送一条消息,开始装配线中的下一步。

CountDownLatch和执行器服务提供了一种阻止直到所有工作线程完成的方法,如果某个进程已划分为不同的并发子任务,则可能会派上用场。

JMS 的要点是提供一种在组件之间进行消息传递的方法。它不会强制实施特定的并发模型。队列和主题表示如何将消息从发布者发送到订阅者。使用队列时,消息将仅发送给一个订阅者。另一方面,主题将消息广播给该主题的所有订阅者。

例如,通过使用观察者模式,可以在单个组件内实现类似的行为。

ForkJoinPool实际上是ExecutorService的一个实现(这可能会突出匹配模型和实现细节的难度)。它只是碰巧针对处理大量小任务进行了优化。

简介: 在 Java 环境中实现某个并发模型的方法有很多种。无论选择哪种并发模型,用于实现程序的接口、类和框架都可能有所不同。