简短指南
数据分解
-
\--→ 几何分解(并行集合)
-
\--→ 递归(Fork/Join)
任务分解
-
\--→ 独立任务(并行集合,数据流任务)
-
\--→ 递归依赖任务(Fork/Join)
-
\--→ 具有相互依赖关系的任务(可组合异步函数,数据流任务,CSP)
-
\--→ 在同一数据上协作的任务(Stm,代理)
流式数据分解
-
\--→ 管道(数据流通道和运算符)
-
\--→ 基于事件的(Actor,主动对象)
详细指南
并行处理集合
当您遇到需要花费一段时间才能处理的集合时,请考虑使用并行集合方法。虽然启用集合以进行并行处理会带来开销,但它通常超过顺序处理的无效性。GPars 为您提供了两种选择
-
GParsPool,它利用高效的 Fork/Join 算法使用 Fork/Join 线程池
-
GParsExecutorsPool,它基于传统的 Java 5 执行器
并行处理集合并链接方法
上面讨论的并行集合方法,例如 eachParallel、findAllParallel 等,为从顺序代码到并发代码提供了简单的迁移路径。但是,当链接多个集合处理方法时,使用 map/reduce 原则更有效。使用基于 GParsPool 的 map/reduce 操作来避免为链中的每个并行方法创建和销毁并行集合的开销。转换将只执行一次 - 在调用检索集合的 parallel 属性时。从那时起,并行树状数据结构将被所有后续调用重用。对于链式并行方法调用,应首选 map/reduce 方法。
处理分层数据结构 - divide-n-conquer
递归算法
树或层次结构是自然并行数据结构。Fork/Join 算法并行处理层次数据或问题。使用 GParsPool 及其 Fork/Join 方便层旨在轻松创建 Fork/Join 计算。
创建用于后台执行的异步函数
长时间运行的计算可以在后台运行,几乎没有语法和性能开销。在 GParsPool 或 GParsExecutorsPool 中使用异步函数
-
callAsync() 异步调用闭包
-
asyncFun() 从原始闭包创建异步闭包。
-
然后可以像原始顺序闭包一样组合异步闭包
为大型数据挖掘构建并发系统
使用数据流通道和运算符来构建独立、异步、事件驱动的计算网络,这些网络处理数据。数据流网络通常用于数据或图像处理、数据挖掘或计算机仿真。
保护共享数据片段免受并发访问
在某些情况下,共享可变状态比其他范式更好地模拟问题域。例如,想象一个由多个用户请求并发访问的购物车。为了保护这种共享资源免受并发修改,请使用 代理。它们将包装数据并保护对数据的访问。
保护多个共享数据元素免受并发访问以保持相互一致性
当共享可变资源的数量增加,并且需要在没有其他线程干预的情况下触摸多个资源时,请使用 软件事务内存 来划定访问数据的并发代码块的 ACI(D) 事务。STM 将让您产生一种错觉,即线程可以无忧无虑地访问数据,而无需担心其他线程。STM 引擎将解决所有冲突并自动重新尝试中止的事务。
在线程/任务之间共享一次性值,例如测试异步计算结果
使用具有线程安全单写多读语义的 DataflowVariables。它们确保读者在另一个线程将值安全写入变量之前无法继续。此外,它们允许注册回调,并在值绑定后立即调用。
将算法显式拆分为具有直接寻址的独立异步对象
在多种形式中使用 Actor。这正是它们的领域 - 独立的活动对象异步交换消息。
用 POJO 外观包装 Actor
主动对象 为 Actor 提供 OO 接口。您将获得 POJO,它们的方法是异步的,并且它们的状态在与 Actor 相同的保证下受到保护。
将算法显式拆分为具有间接寻址的独立并发进程
使用通过 数据流通道 或 Groovy CSP 通信的 数据流任务/进程。与 Actor 不同,您获得确定性行为,允许重用和组合。此外,您还可以结合异步和同步通信通道来限制网络中未处理消息的数量。
通过通道间接寻址各方,削弱了算法组件之间的耦合,并使负载均衡或广播等任务更容易实现。