Quarkus and Virtual Threads – 夸克和虚拟线程

最后修改: 2024年 2月 9日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In the ever-evolving landscape of Java development, the introduction of Java 21 brought forth a revolutionary feature – virtual threads. These lightweight threads, managed by the Java Virtual Machine (JVM), promise to reshape how developers approach concurrency in Java applications. Concurrent application development has long been challenging, often fraught with complexities when managing traditional OS-managed threads.

在 Java 开发不断发展的过程中,Java 21 的推出带来了一项革命性的功能–虚拟线程。这些由Java虚拟机(JVM)管理的轻量级线程有望重塑开发人员处理Java应用程序中并发性的方式。长期以来,并发应用程序开发一直充满挑战,在管理传统操作系统管理的线程时往往充满复杂性。

At its core, the Quarkus framework is a modern, developer-centric toolkit designed for the cloud-native era. It boasts lightning-fast startup times and low memory consumption while offering developers an extensive set of tools for building microservices and cloud-native applications.

Quarkus框架的核心是专为云原生时代设计的以开发人员为中心的现代化工具包。它拥有快如闪电的启动时间和低内存消耗,同时为开发人员提供了一套广泛的工具,用于构建微服务和云原生应用程序。

In this tutorial, we’ll discover how Quarkus leverages Java’s virtual threads, transforming how concurrency is managed in Java applications.

在本教程中,我们将了解Quarkus 如何利用 Java 的虚拟线程,改变 Java 应用程序中的并发管理方式。

2. Understanding Concurrency in Java

2.了解 Java 中的并发性

Java’s journey in managing threads has undergone a significant transformation since its inception. Initially, Java utilized green threads – user-level threads managed by the JVM – emulating multithreading without relying on the native operating system’s capabilities. However, this approach was short-lived and evolved into integrating OS-managed threads in later versions of Java.

Java 自诞生以来,在管理线程方面经历了重大转变。最初,Java 使用绿色线程(由 JVM 管理的用户级线程) 模拟多线程,而不依赖于本地操作系统的功能。然而,这种方法昙花一现,并在后来的 Java 版本中演变为集成操作系统管理的线程。

Traditional threading models in Java, relying on OS-managed threads, posed several challenges. The imperative and reactive models governed the development landscape, each with its strengths and limitations. The imperative model, straightforward in its approach, faced limitations in scalability due to the constraints of OS threads. In contrast, the reactive model, although efficient, demanded a paradigm shift in coding patterns, making it complex and sometimes non-intuitive for developers.

Java 中的传统线程模型依赖于操作系统管理的线程,这带来了一些挑战。命令式模型和反应式模型支配着开发环境,各有其优势和局限性。命令式模型的方法简单明了,但由于操作系统线程的限制,其可扩展性受到了限制。相比之下,反应式模型虽然高效,但要求编码模式的转变,使其变得复杂,有时对开发人员来说并不直观。

3. Introducing Virtual Threads

3.虚拟线程介绍

Java 21’s introduction of virtual threads marks a paradigm shift in concurrency handling. Virtual threads, managed by the JVM, offer a compelling alternative to traditional OS-managed threads. These threads are lightweight entities that promise enhanced concurrency while consuming significantly fewer resources compared to their OS counterparts.

Java 21 引入虚拟线程标志着并发处理模式的转变。由 JVM 管理的虚拟线程为传统操作系统管理的线程提供了一个引人注目的替代方案。这些线程是轻量级实体,承诺增强并发性,同时消耗的资源也比操作系统的同类线程少得多。

Virtual threads bring forth a multitude of advantages, including improved scalability and resource utilization. Unlike OS threads, which are resource-intensive, virtual threads are lightweight and can be created in larger numbers without significantly impacting system resources. This efficiency in resource utilization opens doors for better concurrency handling in Java applications.

虚拟线程具有多种优势,包括更高的可扩展性和资源利用率。与资源密集型的操作系统线程不同,虚拟线程是轻量级的,可以在不对系统资源产生重大影响的情况下创建更多的虚拟线程。

4. Contextualizing Virtual Threads in Quarkus

4.Quarkus 中虚拟线程的上下文化

Understanding how virtual threads integrate within the Quarkus framework provides insights into their practical implementation. Quarkus, designed for cloud-native applications, emphasizes efficiency and performance without compromising developer productivity.

了解虚拟线程如何集成到 Quarkus 框架中,有助于深入了解虚拟线程的实际应用。Quarkus 专为云原生应用而设计,强调效率和性能,同时不影响开发人员的工作效率。

Quarkus leverages virtual threads to enhance its concurrency model, allowing developers to write imperative-style code while benefiting from the advantages of virtual threads. By seamlessly integrating virtual threads into its architecture, Quarkus provides a modern and efficient platform for developing highly concurrent applications.

Quarkus 利用虚拟线程增强其并发模型,允许开发人员编写命令式代码,同时受益于虚拟线程的优势。通过将虚拟线程无缝集成到其架构中,Quarkus 为开发高并发应用程序提供了一个现代而高效的平台。

5. Implementation in Quarkus

5. 在 Quarkus 中实施

To implement virtual threads in Quarkus, we can make the following adjustments to our project.

要在 Quarkus 中实现虚拟线程,我们可以对项目进行以下调整。

5.1. Dependency Configuration

5.1.依赖关系配置

We need to include the necessary dependency in our pom.xml file:

我们需要在 pom.xml 文件中包含必要的依赖关系

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-resteasy-reactive</artifactId>
</dependency>

Additionally, we must ensure that our project is configured to use Java 21 or a higher version:

此外,我们必须确保我们的项目配置为使用 Java 21 或更高版本

<properties>
    <maven.compiler.source>21</maven.compiler.source>
    <maven.compiler.target>21</maven.compiler.target>
</properties>

5.2. Leveraging Virtual Threads Annotations

5.2.利用虚拟线程注解

When integrating virtual threads into our Quarkus application, the key mechanism is the utilization of specific annotations, most notably @RunOnVirtualThread. This annotation serves as a guiding directive, instructing the system to execute designated methods or operations on virtual threads as opposed to the conventional platform threads.

在将虚拟线程集成到我们的 Quarkus 应用程序时,关键机制是使用特定注解,其中最著名的是 @RunOnVirtualThread。该注解可作为指导指令,指示系统在虚拟线程上执行指定的方法或操作,而不是在传统的平台线程上执行。

For example, to facilitate interaction with a remote service, the creation of a remote service interface is imperative. The interface defines the necessary communication protocols:

例如,为了方便与远程服务交互,必须创建一个远程服务接口。接口定义了必要的通信协议:

@Path("/greetings") 
public class VirtualThreadApp {
    @RestClient
    RemoteService service;
    @GET
    @RunOnVirtualThread
    public String process() {
        var response = service.greetings();
        return response.toUpperCase();
    }
}

Within this class, the selective application of @RunOnVirtualThread to the process() method serves as a specific directive. This annotation ensures that this method is executed on virtual threads, allowing for streamlined and efficient handling of operations, such as invoking a remote service. This targeted application of virtual threads enhances the overall concurrency management within the class.

在该类中,@RunOnVirtualThreadprocess()方法的选择性应用是一个特定的指令。该注解可确保该方法在虚拟线程上执行,从而简化并高效地处理调用远程服务等操作。这种有针对性的虚拟线程应用增强了类内的整体并发管理。

6. Performance Comparisons: Traditional vs. Virtual Threads

6.性能比较:传统线程与虚拟线程

An in-depth exploration of the performance disparities between traditional threading models and virtual threads within Quarkus applications provides crucial insights into their operational efficiencies. Through benchmarking tests evaluating scalability, resource utilization, and responsiveness across diverse workloads, we can uncover the distinct advantages that virtual threads offer over their traditional counterparts.

对 Quarkus 应用程序中传统线程模型和虚拟线程之间的性能差异进行深入探讨,可以为了解其运行效率提供重要的启示。通过对各种工作负载的可扩展性、资源利用率和响应速度进行基准测试评估,我们可以发现虚拟线程与传统线程相比所具有的明显优势。

The comparative analysis showcases the superior performance of virtual threads, highlighting their efficiency in managing concurrency. Benchmark results underscore the benefits of virtual threads in terms of enhanced scalability, optimized resource utilization, and improved responsiveness under varying application loads. This empirical evaluation serves as a valuable reference for developers aiming to make informed decisions about the concurrency model best suited for their Quarkus applications.

对比分析展示了虚拟线程的卓越性能,突出了它们在管理并发性方面的效率。基准测试结果强调了虚拟线程在不同应用负载下增强的可扩展性优化的资源利用率提高的响应速度等方面的优势。这一经验性评估为开发人员提供了宝贵的参考,使他们能够就最适合其 Quarkus 应用程序的并发模型做出明智的决策。

7. Challenges and Considerations

7.挑战和考虑因素

In the dynamic landscape of virtual thread utilization, several challenges and considerations merit attention. These aspects play a pivotal role in ensuring a seamless and optimized experience with virtual threads in Quarkus applications.

在虚拟线程利用的动态环境中,有几个挑战和注意事项值得关注。这些方面对于确保 Quarkus 应用程序中虚拟线程的无缝和优化体验起着关键作用。

7.1. Pinning Issues

7.1.引脚问题

Instances may arise where virtual threads encounter blocking due to holding locks or native calls. Overcoming this challenge involves identifying such scenarios and reworking code segments to prevent carrier thread blocking.

虚拟线程可能会遇到因持有锁或本地调用而阻塞的情况。要克服这一难题,就必须识别这类情况,并重新编写代码段,以防止载波线程阻塞。

7.2. Monopolization Concerns

7.2.对垄断的担忧

Long-running computations executed by virtual threads can monopolize carrier threads, potentially impacting the application’s responsiveness. Strategies to manage and optimize thread utilization for intensive computations are essential.

由虚拟线程执行的长时间运行计算会占用载体线程,从而可能影响应用程序的响应速度。管理和优化密集计算线程利用率的策略至关重要。

7.3. Memory Usage and Thread Pool Optimization

7.3.内存使用和线程池优化

Optimizing thread pools and managing memory usage becomes critical when leveraging virtual threads. Careful consideration of thread pool configurations and memory management prevents excessive thread pool elasticity and memory overhead.

利用虚拟线程时,优化线程池和管理内存使用情况变得至关重要。仔细考虑线程池配置和内存管理可防止线程池弹性过大和内存开销过高。

7.4. Ensuring Thread Safety

7.4.确保螺纹安全

Maintaining thread-safe implementations in a virtual thread environment is crucial to prevent data inconsistencies or race conditions when multiple virtual threads access shared resources concurrently.

在虚拟线程环境中保持线程安全的实现,对于防止多个虚拟线程同时访问共享资源时出现数据不一致或竞赛条件至关重要。

8. Best Practices and Recommendations

8.最佳做法和建议

Using virtual threads effectively requires following best practices and recommendations to ensure optimal performance and maintainability.

有效使用虚拟线程需要遵循最佳实践和建议,以确保最佳性能和可维护性。

8.1. Strategies for Optimizing Virtual Thread Usage

8.1.优化虚拟线程使用的策略

To optimize virtual thread usage, we need to:

为了优化虚拟线程的使用,我们需要

  • Identify Blocking Operations: Analyze and minimize code segments that cause virtual threads to block, ensuring smoother execution.
  • Use Asynchronous Operations: Implement non-blocking I/O and asynchronous processing to increase virtual thread concurrency and efficiency.
  • Monitor Thread Pools: Regularly check and adjust thread pool configurations to optimize resource use and prevent unnecessary expansion.

8.2. Recommendations for Developers

8.2.对开发商的建议

The following can be considered as recommendations:

建议如下

  • Focus on Thread Safety: Ensure thread safety in shared resources to avoid data inconsistencies and race conditions.
  • Continuously Refactor: Regularly update and improve code for efficient, non-blocking execution.
  • Share Knowledge: Engage in collaborative learning by sharing experiences and best practices about virtual threads to collectively overcome challenges and enhance efficiency.

9. Conclusion

9.结论

In this article, we delved into the adoption of virtual threads in Quarkus, shedding light on its plethora of benefits, including enhanced concurrency, optimized resource utilization, and improved scalability. However, we saw that challenges like thread pinning, monopolization, and memory management demand meticulous consideration and strategic handling to fully reap the benefits of virtual threads.

在本文中,我们深入探讨了在 Quarkus 中采用虚拟线程的问题,揭示了虚拟线程的诸多好处,包括增强并发性、优化资源利用率和提高可扩展性。不过,我们也看到,要充分发挥虚拟线程的优势,还需要对线程钉住、垄断和内存管理等挑战进行缜密考虑和策略处理。

The complete source code for this tutorial is available over on GitHub.

本教程的完整源代码可在 GitHub. 上获取。