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

问题描述 投票:0回答:3

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

文章重点介绍三种并发模型

  1. 平行工人

第一个并发模型就是我所说的并行工作者模型。 传入的工作分配给不同的worker.

  1. 装配线

工人的组织方式就像 工人 在装配线上 工厂。每个工人只执行全部工作的一部分。当那个 部分完成工人将工作转发给下一个工人。

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

  1. 函数式并行

函数式并行的基本思想是你实现你的 使用函数调用的程序。函数可以看作是“agents”或者 互相发送消息的“actors”,就像在 流水线并发模型(AKA 反应或事件驱动 系统)。当一个函数调用另一个函数时,类似于发送 一条消息。

现在我要映射java API对这三个概念的支持

  1. Parallel Workers:是ExecutorServiceThreadPoolExecutorCountDownLatch API吗?

  2. Assembly Line:将事件发送到像 JMS 这样的消息传递系统,并使用 Queues & Topics.

    的消息传递概念
  3. 函数式并行ForkJoinPool 在某种程度上和 Java 8 流。与流相比,ForkJoin 池很容易理解。

我在映射这些并发模型时是否正确?如果不是请纠正我。

java multithreading executorservice countdownlatch forkjoinpool
3个回答
18
投票

这些模型中的每一个都从一般的角度说明了工作是如何完成/拆分的,但是在实施方面,它实际上取决于您的具体问题。一般我是这样看的:

  1. Parallel Workers:生产者在某处创建新工作(例如在
    BlockingQueue
    中),许多线程(通过
    ExecutorService
    )并行处理这些工作。当然,您也可以使用
    CountDownLatch
    ,但这意味着您希望在处理完
    N
    子问题后触发一个动作(例如,您知道您的大问题可能会分成
    N
    小问题,检查 the第二个例子在这里)。
  2. 装配线:对于每个中间步骤,您都有一个
    BlockingQueue
    和一个
    Thread
    或一个
    ExecutorService
    。在每一步中,作业都从一个
    BlickingQueue
    中取出并放入下一个,以进行进一步处理。关于 JMS 的想法:JMS 用于连接分布式组件,是 Java EE 的一部分,不被认为用于高并发上下文(消息通常在处理之前保存在硬盘上)。
  3. Functional Parallelism
    ForkJoinPool
    是关于如何实现它的一个很好的例子。

6
投票

一个很好的问题,但答案可能不太令人满意。列出的并发模型显示了您可能想要实现并发系统的一些方法。 API 提供了用于实现这些模型的工具。

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

CountDownLatch 和 ExecutorService 提供了一种阻塞方式,直到所有 worker 都完成,如果某个进程已被划分为不同的并发子任务,这可能会派上用场。

JMS 的重点是提供组件间消息传递的方式。它不强制执行特定的并发模型。队列和主题表示消息如何从发布者发送到订阅者。当您使用队列时,消息只会发送给一个订阅者。另一方面,主题将消息广播给该主题的所有订阅者。

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

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

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


0
投票

Actor 模型是流水线的另一个例子。例如:阿卡

© www.soinside.com 2019 - 2024. All rights reserved.