领先的免费Web技术教程,涵盖HTML到ASP.NET

网站首页 > 知识剖析 正文

JDK 21的Virtual Threads:Java 虚拟线程的简介和演示

nixiaole 2025-06-08 23:18:50 知识剖析 1 ℃

引言: 随着计算机系统的发展和多核处理器的普及,编写高效且可扩展的并发程序变得越来越重要。为了满足这一需求,Java开发团队在JDK 21中引入了JEP 444,也被称为Virtual Threads(虚拟线程)。本文将介绍Virtual Threads的概念、其工作原理以及对Java开发人员和并发编程的影响。

  1. 背景和问题: 在过去的Java版本中,线程是与操作系统的本机线程(Native Thread)直接映射的。这种映射关系导致了一些问题。首先,创建和销毁线程需要耗费大量的系统资源。其次,线程的调度和上下文切换也需要相应的时间和开销。这些问题在高并发应用程序中尤为明显,可能导致性能下降和资源浪费。
  2. Virtual Threads的概念: Virtual Threads是一种轻量级的、用户级别的线程实现。与传统的本机线程不同,Virtual Threads不直接映射到操作系统线程,而是由Java虚拟机(JVM)管理和调度。Virtual Threads的设计目标是提供一种高效、可扩展且开销较低的并发编程模型。
  3. 工作原理: Virtual Threads通过Fork/Join框架的扩展实现。在JDK 21中,引入了ForkJoinPool的新功能,使其能够处理Virtual Threads。ForkJoinPool是Java中用于实现任务并行的框架,通过工作窃取算法提高并行性能。在JDK 21中,ForkJoinPool可以直接支持Virtual Threads,从而提供更好的性能和可伸缩性。
  4. Virtual Threads的优势: Virtual Threads带来了几个重要的优势。首先,由于不需要与操作系统的本机线程直接映射,Virtual Threads的创建和销毁成本较低。其次,Virtual Threads的调度和上下文切换开销也较小,这在高并发场景下特别重要。另外,Virtual Threads还可以提供更好的资源利用率,因为JVM可以根据实际情况调整线程的数量。
  5. 使用Virtual Threads: 使用Virtual Threads并不需要对现有的Java并发代码进行大规模修改。开发人员可以通过使用ForkJoinPool的新API,以及新的ExecutorService接口和相关工具类,轻松地在现有代码中使用Virtual Threads。这使得迁移到Virtual Threads变得相对容易,而且可以逐步进行。
  6. 注意事项和挑战: 尽管Virtual Threads带来了很多优势,但在使用过程中仍需注意一些事项。首先,由于Virtual Threads不是本机线程,因此与传统线程相关的一些API和行为可能会有所不同。开发人员需要对这些差异进行了解,并适当调整代码。其次,虽然Virtual Threads可以提高性能和可伸缩性,但滥用它们可能会导致资源竞争和死锁等并发问题。因此,使用Virtual Threads时需要谨慎,并遵循最佳实践。

结论: JEP 444引入的Virtual Threads为Java开发人员提供了一种高效、可扩展且开销较低的并发编程模型。它通过与操作系统的本机线程解耦,减少了线程创建和销毁的成本,并改善了调度和上下文切换的效率。使用Virtual Threads可以提高并发程序的性能和资源利用率,为开发人员提供更好的编程体验。然而,使用Virtual Threads时需要注意差异和挑战,并遵循最佳实践,以确保正确和高效地使用这项技术。

演示代码放在:GitHub - guwan/jdk21Demo: Demonstration of Some New Features of JDK 21

先使用Thread.ofVirtual演示一个简单的

我们使用Thread.ofVirtual()创建一个Virtual Thread,并在其start()方法中指定线程的执行逻辑,这里我们简单地打印线程信息。然后,我们使用join()方法等待线程执行完成。

使用Thread.ofVirtual()可以方便地创建和执行Virtual Thread,它提供了一种简洁的方式来利用Virtual Threads的优势。


public class VirtualThreadsDemo {
    public static void main(String[] args) {
        // 创建并执行Virtual Thread
        Thread virtualThread = Thread.ofVirtual().start(() -> {
            System.out.println("Running Virtual Thread: " + Thread.currentThread());
        });

        // 等待线程执行完成
        try {
            virtualThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


我们也可以用Executors创建虚拟线程

我们使用
Executors.newVirtualThreadExecutor()方法创建了一个支持Virtual Threads的线程池。然后,我们使用executor.submit()方法提交了两个并发任务,并通过Future对象获取任务的结果。每个任务都会在自己的Virtual Thread上执行,并打印执行线程的信息。最后,我们输出了任务的结果,并调用executor.shutdown()关闭线程池。


import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;


public class VirtualThreadsDemo2 {
    public static void main(String[] args) {

        // 创建一个支持Virtual Threads的线程池
        try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {

            try {
                // 提交并发任务
                Future<String> future1 = executor.submit(() -> {
                    System.out.println("Running task 1 on Virtual Thread: " + Thread.currentThread());
                    return "Task 1 completed.";
                });

                Future<String> future2 = executor.submit(() -> {
                    System.out.println("Running task 2 on Virtual Thread: " + Thread.currentThread());
                    return "Task 2 completed.";
                });

                // 获取任务结果
                String result1 = future1.get();
                String result2 = future2.get();

                System.out.println("Result 1: " + result1);
                System.out.println("Result 2: " + result2);
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            } finally {
                // 关闭线程池
                executor.shutdown();
            }
        }
    }
}


参考链接:

  • JEP 444: https://openjdk.org/jeps/444
  • Virtual Threads Early-Access Builds: https://jdk.java.net/loom/
  • ForkJoinPool Documentation: https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/ForkJoinPool.html

Tags:

最近发表
标签列表