大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
并发与流
Scala 并发从 Future(标准库)到 Akka/Pekko Streams、ZIO Streams、FS2(Cats Effect)层层递进。对照 /roadmaps/scala「Concurrency & Streams」节点。
学习目标
- 使用
Future与ExecutionContext做异步组合 - 了解 Pekko Streams 的 Source/Flow/Sink 模型
- 知道 ZIO / FS2 流式处理的基本概念
核心概念
Future 组合
import scala.concurrent.{Future, ExecutionContext}
import scala.util.{Success, Failure}
def fetchTitle(id: Long)(using ec: ExecutionContext): Future[String] =
Future {
if id <= 0 then throw new IllegalArgumentException("bad id")
else s"Title-$id"
}
def fetchMany(ids: List[Long])(using ec: ExecutionContext): Future[List[String]] =
Future.sequence(ids.map(fetchTitle))
given ec: ExecutionContext = ExecutionContext.global
val result = fetchMany(List(1L, 2L, 3L))
result.onComplete {
case Success(xs) => println(xs.mkString(", "))
case Failure(e) => println(s"error: ${e.getMessage}")
}
Thread.sleep(500)
Future.sequence 并行多个 Future;生产环境应配置专用线程池而非 global。
Pekko Streams 概览
import org.apache.pekko.actor.typed.{ActorSystem, Behaviors}
import org.apache.pekko.stream.scaladsl.{Source, Sink, Flow}
import org.apache.pekko.stream.Materializer
given system: ActorSystem[Nothing] = ActorSystem(Behaviors.empty, "streams")
given mat: Materializer = Materializer(system)
val stream =
Source(1 to 100)
.filter(_ % 2 == 0)
.map(_ * 10)
.runWith(Sink.seq)
stream.foreach(seq => println(s"count=${seq.size}, head=${seq.headOption}"))
Source 产数据、Flow 变换、Sink 消费;背压(backpressure)由 Stream 协议处理。
FS2 / ZIO Streams(概念)
// FS2 风格片段
import fs2.Stream
val s: Stream[IO, Int] =
Stream.emits(1 to 5).filter(_ > 2).map(_ * 2)
// ZIO Stream
import zio.stream.*
val z: ZStream[Any, Throwable, String] =
ZStream.fromIterable(1 to 3).map(n => s"item-$n")
FS2 与 ZIO Streams 纯函数式、资源安全(bracket),适合 Kafka / 文件管道。
与 Java 对照
| Scala | Java |
|---|---|
Future | CompletableFuture |
| Pekko Streams | Reactive Streams / Flow API(Java 9+) |
| Actor | 无内置;Loom Virtual Thread 不同模型 |
| FS2 / ZIO | Project Reactor(Spring WebFlux) |
Java Virtual Thread 简化阻塞代码;Scala Actor/Stream 强调消息与背压,选型取决于团队范式。
练习
- 用
Future实现超时:Future.firstCompletedOf或recover - 写 Pekko Stream 将行文件读入并计数
- 对比 Java
CompletableFuture.allOf与Future.sequence
小结
Future 入门,Pekko Streams 管背压,FS2/ZIO 管 FP 流式管道。 下一课综合练习。见 scala-essentials。