1. 简介

协程(Coroutines)是 Java 线程的一种替代方案,它能够在极高并发场景下执行可中断的任务。虽然 Project Loom 正在推进原生协程支持,但在其正式落地之前,我们仍需依赖第三方库来实现类似能力。

本文将介绍 Quasar —— 一个为 Java 提供协程支持的成熟库。它通过轻量级线程(Fibers)实现高效的并发模型,让你在不增加系统负担的前提下,轻松管理成千上万的并发任务。

✅ 踩坑提示:如果你正在为高并发系统做技术选型,又受限于传统线程的资源开销,Quasar 是一个值得深入研究的方案。但注意,它依赖字节码增强,对某些运行环境(如部分云平台或安全限制严格的容器)可能存在兼容性问题。

2. 环境搭建

当前最新版 Quasar 要求 Java 11 或更高版本。不过,旧版本(如 0.7.x)支持 Java 7 和 8,因此在老项目中也能使用,只需注意版本兼容性即可。

2.1 核心依赖

Quasar 提供了三个核心模块,通常你需要根据需求选择引入:

<dependency>
    <groupId>co.paralleluniverse</groupId>
    <artifactId>quasar-core</artifactId>
    <version>0.8.0</version>
</dependency>
<dependency>
    <groupId>co.paralleluniverse</groupId>
    <artifactId>quasar-actors</artifactId>
    <version>0.8.0</version>
</dependency>
<dependency>
    <groupId>co.paralleluniverse</groupId>
    <artifactId>quasar-reactive-streams</artifactId>
    <version>0.8.0</version>
</dependency>
  • quasar-core:必选,提供 Fiber 和协程核心能力
  • quasar-actors:可选,用于支持 Actor 模型通信
  • quasar-reactive-streams:可选,集成 Reactive Streams

2.2 字节码增强机制

Quasar 的核心原理是通过 字节码 instrumentation(增强) 实现协程的挂起与恢复。它不会直接使用操作系统线程,而是将 Fiber 调度在少量真实线程上,从而实现 M:N 的轻量调度。

实现字节码增强有两种方式:

  • ⚙️ 编译期增强(Build-time instrumentation)
  • 🚀 运行时增强(Runtime instrumentation)—— 推荐

✅ 推荐使用 Java Agent 方式 在运行时完成增强。这种方式无需修改构建流程,兼容性更好,调试也更方便。

2.3 使用 Maven 配置 Java Agent

要让 Maven 在运行时自动加载 Quasar 的 agent,需配置两个插件。

第一步:添加 maven-dependency-plugin 获取 jar 路径

<plugin>
    <artifactId>maven-dependency-plugin</artifactId>
    <version>3.1.1</version>
    <executions>
        <execution>
            <id>getClasspathFilenames</id>
            <goals>
                <goal>properties</goal>
            </goals>
        </execution>
    </executions>
</plugin>

该插件会生成一个 Maven 属性 ${co.paralleluniverse:quasar-core:jar},指向 classpath 下的 quasar-core.jar 文件路径。

第二步:使用 exec-maven-plugin 启动应用并加载 agent

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>3.1.0</version>
    <configuration>
        <workingDirectory>target/classes</workingDirectory>
        <executable>java</executable>
        <arguments>
            <argument>-javaagent:${co.paralleluniverse:quasar-core:jar}</argument>
            <argument>-classpath</argument>
            <classpath/>
            <argument>com.example.QuasarHelloWorld</argument>
        </arguments>
    </configuration>
</plugin>

⚠️ 注意:原示例中 <executable>echo</executable> 显然是笔误,实际应为 java,否则无法运行程序。

第三步:执行命令启动应用

mvn compile dependency:properties exec:exec

这条命令会:

  1. 编译代码
  2. 解析依赖路径
  3. 使用 Java Agent 启动主类

✅ 小技巧:你也可以手动运行 Java 命令,效果等价:

java -javaagent:/path/to/quasar-core-0.8.0.jar -cp "classes:lib/*" com.example.QuasarHelloWorld

3. 协程实现:使用 Fiber

Quasar 的协程是通过 Fiber 实现的。你可以把 Fiber 理解为“用户态线程”或“绿色线程”,由 JVM 内部调度,而非操作系统。

3.1 Fiber 的优势

特性 Thread Fiber
内存占用 高(MB级栈) 极低(KB级,按需扩展)
创建速度 慢(系统调用) 快(纯内存操作)
上下文切换 OS调度,开销大 用户态切换,极轻量
并发数量 几千 百万级

✅ 简单粗暴地说:Fiber 就是线程的“协程版”,适合 I/O 密集型或高并发任务。

3.2 创建并启动 Fiber

使用方式非常直观,类似 ThreadRunnable

new Fiber<Void>(() -> {
    System.out.println("Inside fiber coroutine...");
}).start();
  • Fiber<T>:泛型表示返回值类型,Void 表示无返回
  • ✅ Lambda 中可以包含阻塞调用(如 Thread.sleep()),但不会阻塞底层线程
  • ✅ 调用 start() 后 Fiber 开始执行,调度由 Quasar 自动管理

3.3 更复杂的示例:带返回值和异常处理

Fiber<Integer> fiber = new Fiber<>(() -> {
    System.out.println("Fiber is running...");
    Fiber.sleep(1000); // Quasar 提供的非阻塞 sleep
    if (Math.random() > 0.5) {
        throw new RuntimeException("Something went wrong");
    }
    return 42;
});

fiber.start();

try {
    Integer result = fiber.get(); // 获取结果(阻塞等待)
    System.out.println("Result: " + result);
} catch (ExecutionException e) {
    System.err.println("Fiber failed: " + e.getCause().getMessage());
}

✅ 注意:Fiber.sleep() 是协作式挂起,不会占用底层线程,而 Thread.sleep() 会。但在 Fiber 中调用 Thread.sleep() 也不会“真阻塞”,Quasar 会将其转换为可调度的挂起点。

4. 总结

本文介绍了如何通过 Quasar 库在 Java 中实现协程编程。我们完成了以下内容:

  • ✅ 引入 Quasar 核心依赖
  • ✅ 配置 Java Agent 实现字节码增强
  • ✅ 使用 Fiber 创建轻量级协程
  • ✅ 展示了基本用法与异常处理

虽然示例简单,但已涵盖 Quasar 的核心使用模式。实际上,Quasar 还支持:

  • Actor 模型(quasar-actors
  • 与 Reactive Streams 集成
  • Channel 通信机制
  • 更精细的调度策略

📌 项目源码已托管至 GitHub:https://github.com/example-java/quasar-demo

如果你正在构建高并发服务(如网关、消息中间件、爬虫调度器等),Quasar 提供了一种比传统线程池更优雅、更高效的解决方案。尽管 Project Loom 终将到来,但在它普及之前,Quasar 依然是生产级协程方案的有力候选。


原始标题:Intro to Coroutines with Quasar