使用Java虚拟线程开发一个Web服务器可以显著提升并发能力,同时保持代码简洁。在这个示例中,我们将使用 Java 21 的虚拟线程实现一个简单的 HTTP Web 服务器,逐步解释每个部分的代码。

实现目标

  1. 通过虚拟线程处理 HTTP 请求。
  2. 创建一个简单的 Web 服务器来响应客户端请求。
  3. 适配 IO 阻塞的情况,让每个请求独占一个虚拟线程。

代码示例:Web服务器的实现

import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpExchange;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
public class VirtualThreadHttpServer {
public static void main(String[] args) throws IOException {
// 1. 创建 HTTP 服务器,绑定到本地端口 8080
HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
// 2. 注册 HTTP 处理程序(Handler),处理 "/hello" 路径
server.createContext("/hello", new HelloHandler());
// 3. 设置线程池,使用虚拟线程处理每个请求
server.setExecutor(Executors.newVirtualThreadPerTaskExecutor());
// 4. 启动服务器
server.start();
System.out.println("Server is listening on http://localhost:8080...");
}
// 处理 HTTP 请求的 Handler
static class HelloHandler implements HttpHandler {
@Override
public void handle(HttpExchange exchange) throws IOException {
// 5. 设置响应头和响应体内容
String response = "Hello, Virtual Threads!";
exchange.sendResponseHeaders(200, response.getBytes().length);
// 6. 将响应内容写入输出流并关闭流
try (OutputStream os = exchange.getResponseBody()) {
os.write(response.getBytes());
}
}
}
}

代码讲解

  1. 创建 HTTP 服务器

    HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);

    这里我们使用 com.sun.net.httpserver.HttpServer 创建一个 HTTP 服务器,并绑定到 localhost:8080 端口。第二个参数 0 表示允许的连接队列大小为默认值。

  2. 注册请求处理程序(Handler)

    server.createContext("/hello", new HelloHandler());

    我们通过 createContext 注册一个路径为 /hello 的处理器。当客户端访问该路径时,会触发对应的处理逻辑。

  3. 使用虚拟线程池

    server.setExecutor(Executors.newVirtualThreadPerTaskExecutor());

    在这里,我们使用了 虚拟线程池 来处理每个 HTTP 请求。newVirtualThreadPerTaskExecutor 是 Java 提供的一个工厂方法,能够为每个任务创建一个新的虚拟线程。

  4. 启动服务器

    server.start();

    服务器启动后,将开始监听客户端的 HTTP 请求。

  5. 处理 HTTP 请求

    String response = "Hello, Virtual Threads!";
    exchange.sendResponseHeaders(200, response.getBytes().length);

    这里我们定义了一个简单的响应消息 "Hello, Virtual Threads!",并通过 sendResponseHeaders 发送状态码 200 和响应内容长度。

  6. 输出响应内容并关闭流

    try (OutputStream os = exchange.getResponseBody()) {
    os.write(response.getBytes());
    }

    将响应内容写入 HttpExchange 的输出流,并在完成后自动关闭流。


如何运行

  1. 确保你使用的是 Java 21 及以上版本。
  2. 将上述代码保存为 VirtualThreadHttpServer.java
  3. 编译并运行:
    javac VirtualThreadHttpServer.java
    java VirtualThreadHttpServer
  4. 打开浏览器访问:http://localhost:8080/hello,你会看到如下输出:
    Hello, Virtual Threads!

虚拟线程的优势

  1. 处理大量并发请求:每个请求都有自己的虚拟线程,避免了传统线程池的限制,支持上万甚至更多的并发连接。
  2. 简化代码:通过虚拟线程,异步逻辑可以用同步的方式编写,无需复杂的回调或 CompletableFuture
  3. 低资源消耗:虚拟线程非常轻量级,不会像系统线程一样占用大量内存。

扩展功能建议

  • 日志记录:添加请求日志,记录每次访问的路径和时间。
  • 异步数据库访问:处理请求时查询数据库并返回结果。
  • REST API:实现更多的 HTTP 处理程序来支持不同的 REST API 请求。

这个示例展示了虚拟线程如何简化 Web 服务器的开发,并在高并发场景下提供优异的性能。

posted on   张伯灵  阅读(76)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了



点击右上角即可分享
微信分享提示