为什么虚拟线程无法在虚拟线程池中执行?

环境: java21
问题: methods5不会输出log.info的内容, methods6正常打印log.info的内容

    private static void methods5() {
        ThreadFactory tf = Thread.ofVirtual().factory();
        try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
            Thread vt = tf.newThread(() -> log.info("vt task executed."));
            for (int i = 0; i < 5; i++) {
                executor.submit(vt).get();
            }
        } catch (ExecutionException | InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    private static void methods6() {
        try (ExecutorService executor = Executors.newFixedThreadPool(5)) {
            Thread thread = new Thread(() -> log.info("thread task executed."));
            for (int i = 0; i < 5; i++) {
                try {
                    executor.submit(thread).get();
                } catch (InterruptedException | ExecutionException e) {
                    // 处理异常
                }
            }
        }
    }
阅读 801
1 个回答

正确的做法是给调度器传真正的线程对象,它会以虚拟线程形式运行,而不是给它传虚拟线程,要么你就干脆直接对虚拟线程使用start()方法
改法一:

private static void methods5() {
  try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
      Thread vt = new Thread(() -> System.out.println("vt task executed."));
      for (int i = 0; i < 5; i++) {
          executor.submit(vt).get();
      }
  } catch (ExecutionException | InterruptedException e) {
      throw new RuntimeException(e);
  }
  }

改法二:

private static void methods5() {
  try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
      for (int i = 0; i < 5; i++) {
          executor.submit(()->{
              System.out.println("vt task executed.");
          });
      }
  }
}

另外虚拟线程没有必要使用池化技术,因为创建和销毁的代价非常小,池化的话属于是违背初心了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题