概念

人们喜欢多样性,但经常无法做出适当的选择。由于 GPars 提供了几种并发范式,我们决定构建一个简化的指南来帮助用户为其任务选择正确的概念。

简短指南

数据分解

  • \--→ 几何分解(并行集合)

  • \--→ 递归(Fork/Join)

任务分解

  • \--→ 独立任务(并行集合,数据流任务)

  • \--→ 递归依赖任务(Fork/Join)

  • \--→ 具有相互依赖关系的任务(可组合异步函数,数据流任务,CSP)

  • \--→ 在同一数据上协作的任务(Stm,代理)

流式数据分解

  • \--→ 管道(数据流通道和运算符)

  • \--→ 基于事件的(Actor,主动对象)


详细指南

并行处理集合

当您遇到需要花费一段时间才能处理的集合时,请考虑使用并行集合方法。虽然启用集合以进行并行处理会带来开销,但它通常超过顺序处理的无效性。GPars 为您提供了两种选择

  • GParsPool,它利用高效的 Fork/Join 算法使用 Fork/Join 线程池

  • GParsExecutorsPool,它基于传统的 Java 5 执行器


并行处理集合并链接方法

上面讨论的并行集合方法,例如 eachParallelfindAllParallel 等,为从顺序代码到并发代码提供了简单的迁移路径。但是,当链接多个集合处理方法时,使用 map/reduce 原则更有效。使用基于 GParsPoolmap/reduce 操作来避免为链中的每个并行方法创建和销毁并行集合的开销。转换将只执行一次 - 在调用检索集合的 parallel 属性时。从那时起,并行树状数据结构将被所有后续调用重用。对于链式并行方法调用,应首选 map/reduce 方法。


处理分层数据结构 - divide-n-conquer 递归算法

树或层次结构是自然并行数据结构。Fork/Join 算法并行处理层次数据或问题。使用 GParsPool 及其 Fork/Join 方便层旨在轻松创建 Fork/Join 计算。


创建用于后台执行的异步函数

长时间运行的计算可以在后台运行,几乎没有语法和性能开销。在 GParsPoolGParsExecutorsPool 中使用异步函数

  • callAsync() 异步调用闭包

  • asyncFun() 从原始闭包创建异步闭包。

  • 然后可以像原始顺序闭包一样组合异步闭包


为大型数据挖掘构建并发系统

使用数据流通道和运算符来构建独立、异步、事件驱动的计算网络,这些网络处理数据。数据流网络通常用于数据或图像处理、数据挖掘或计算机仿真。


保护共享数据片段免受并发访问

在某些情况下,共享可变状态比其他范式更好地模拟问题域。例如,想象一个由多个用户请求并发访问的购物车。为了保护这种共享资源免受并发修改,请使用 代理。它们将包装数据并保护对数据的访问。


保护多个共享数据元素免受并发访问以保持相互一致性

当共享可变资源的数量增加,并且需要在没有其他线程干预的情况下触摸多个资源时,请使用 软件事务内存 来划定访问数据的并发代码块的 ACI(D) 事务。STM 将让您产生一种错觉,即线程可以无忧无虑地访问数据,而无需担心其他线程。STM 引擎将解决所有冲突并自动重新尝试中止的事务。


在线程/任务之间共享一次性值,例如测试异步计算结果

使用具有线程安全单写多读语义的 DataflowVariables。它们确保读者在另一个线程将值安全写入变量之前无法继续。此外,它们允许注册回调,并在值绑定后立即调用。


将算法显式拆分为具有直接寻址的独立异步对象

在多种形式中使用 Actor。这正是它们的领域 - 独立的活动对象异步交换消息。


用 POJO 外观包装 Actor

主动对象 为 Actor 提供 OO 接口。您将获得 POJO,它们的方法是异步的,并且它们的状态在与 Actor 相同的保证下受到保护。


将算法显式拆分为具有间接寻址的独立并发进程

使用通过 数据流通道Groovy CSP 通信的 数据流任务/进程。与 Actor 不同,您获得确定性行为,允许重用和组合。此外,您还可以结合异步和同步通信通道来限制网络中未处理消息的数量。

通过通道间接寻址各方,削弱了算法组件之间的耦合,并使负载均衡或广播等任务更容易实现。