龙空技术网

Java 19 中虚拟线程的调试与 thread dump 的使用

成富Alex 90

前言:

如今朋友们对“cmd532加密算法”大约比较着重,姐妹们都需要剖析一些“cmd532加密算法”的相关内容。那么小编也在网络上汇集了一些关于“cmd532加密算法””的相关资讯,希望姐妹们能喜欢,大家一起来了解一下吧!

#头条创作挑战赛#

在使用了 Java 19 的虚拟线程之后,一个很现实的问题是:怎么调试虚拟线程中运行的代码?简单来说,虚拟线程的调试与平台线程并没有什么区别。它们都是 java.lang.Thread 的对象。现有的工具都可以支持。

下面的代码是使用了虚拟线程的 Web 服务,可以返回服务器的当前时间。服务器实现使用的是 JDK 自带的 HttpServer。通过 Executors.newThreadPerTaskExecutor 方法,创建了使用虚拟线程的 ExecutorService,并为虚拟线程指定了名称。每个请求的返回结果中,都会包含处理该请求的线程名称。

public class SimpleHttpServer {  public static void main(String[] args) throws IOException {    new SimpleHttpServer().start();  }  public void start() throws IOException {    var server = HttpServer.create(new InetSocketAddress(8000), 0);    server.createContext("/time", new TimeHandler());    server.setExecutor(        Executors.newThreadPerTaskExecutor(            Thread.ofVirtual().name("time-server-", 1).factory()));    server.start();    System.out.println("Time server started");  }  private static class TimeHandler implements HttpHandler {    @Override    public void handle(HttpExchange exchange) throws IOException {      var response =          String.format(              "%s, reported on %s",              LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME),              Thread.currentThread().getName());      exchange.sendResponseHeaders(200, response.length());      try (var out = exchange.getResponseBody()) {        out.write(response.getBytes());      }    }  }}

运行的效果如下图所示:

时间服务的运行效果

当需要进行调试时,同样是在代码中添加断点、当有请求时,可以自动进入断点调试,从中可以看到当前线程。

调试界面

thread dump 在查找错误原因时非常有用。虚拟线程也会出现在 thread dump 中。由于虚拟线程的数量可能很大,之前的文本格式的 thread dump 不利于进行分析。Java 19 的 thread dump 新增了一种 JSON 格式,更加方便工具来处理 thread dump。

使用命令行时,首先通过 jps 命令获取到 JVM 进程的 ID,再通过 jcmd 命令来获取 thread dump。使用参数 -format=json 表示 JSON 格式的 thread dump。

$ jcmd  <pid> Thread.dump_to_file -format=json <file>

也可以使用 JDK Mission Control 这样的工具来获取。

使用 JMC 获取 thread dump

下面给出了 thread dump 的部分内容,从中可以看到正在处理请求的虚拟线程。

{        "container": "java.util.concurrent.ThreadPerTaskExecutor@14b0ade5",        "parent": "<root>",        "owner": null,        "threads": [         {           "tid": "55",           "name": "time-server-8",           "stack": [              "java.base\/jdk.internal.vm.Continuation.yield(Continuation.java:357)",              "java.base\/java.lang.VirtualThread.yieldContinuation(VirtualThread.java:370)",              "java.base\/java.lang.VirtualThread.parkNanos(VirtualThread.java:532)",              "java.base\/java.lang.VirtualThread.doSleepNanos(VirtualThread.java:713)",              "java.base\/java.lang.VirtualThread.sleepNanos(VirtualThread.java:686)",              "java.base\/java.lang.Thread.sleep(Thread.java:538)",              "io.vividcode.loomfaq.app.SimpleHttpServer$TimeHandler.handle(SimpleHttpServer.java:47)",              "jdk.httpserver\/com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:98)",              "jdk.httpserver\/sun.net.httpserver.AuthFilter.doFilter(AuthFilter.java:82)",              "jdk.httpserver\/com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:101)",              "jdk.httpserver\/sun.net.httpserver.ServerImpl$Exchange$LinkHandler.handle(ServerImpl.java:752)",              "jdk.httpserver\/com.sun.net.httpserver.Filter$Chain.doFilter(Filter.java:98)",              "jdk.httpserver\/sun.net.httpserver.ServerImpl$Exchange.run(ServerImpl.java:719)",              "java.base\/java.util.concurrent.ThreadPerTaskExecutor$TaskRunner.run(ThreadPerTaskExecutor.java:314)",              "java.base\/java.lang.VirtualThread.run(VirtualThread.java:287)",              "java.base\/java.lang.VirtualThread$VThreadContinuation.lambda$new$0(VirtualThread.java:174)",              "java.base\/jdk.internal.vm.Continuation.enter0(Continuation.java:327)",              "java.base\/jdk.internal.vm.Continuation.enter(Continuation.java:320)"           ]         }        ],        "threadCount": "1"      }

标签: #cmd532加密算法