【问题标题】:Not able us Virtual Threads using Project Loom无法使用 Project Loom 的虚拟线程
【发布时间】:2020-10-19 23:20:44
【问题描述】:

我正在探索 Project Loom 中的虚拟线程。文档用以下简单的代码行直截了当:

Thread.startVirtualThread(() -> {
    System.out.println("Hello, Loom!");
});

或者

Thread t = Thread.builder().virtual().task(() -> { ... }).start();

这两个我都试过了,第一个,我收到一个错误 方法 startVirtualThread(() -> {}) 未为类型 Thread 定义

第二个 - 未定义 Thread 类型的方法 builder()

一次浏览,发现需要lombok,也安装了lombok。但是它没有出现在 Eclipse About 部分,我可以使用 lombok,但我的问题仍然没有解决。

以下链接显示文档,我指的是。

enter link description here

示例代码:

 public class threads {
    public void simpleThread() {
        Thread start = Thread.builder().virtual().task(() -> {
            System.out.println("Hello World");
        }).start();
        Thread.startVirtualThread(() -> {
            System.out.println("Hello, Loom!");
        });
    }
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        threads trd = new threads();
        trd.simpleThread();
    }
}

【问题讨论】:

  • 您是否使用包含 Loom 的特殊 Java 版本?因为这在 Java 本身中还不存在。
  • 你不应该需要龙目岛。正如@MarkRotteveel 提到的,请确保您使用的是来自jdk.java.net/loom 的构建
  • @MarkRotteveel 我尝试过使用 OpenJDK 14、15、16 以及带有 loom 的版本。参考这个:jdk.java.net/loom

标签: java multithreading green-threads


【解决方案1】:

看起来旧版本的 Eclipse 在调用与 Loom 相关的新 Thread 方法时出现编译错误。

请尝试使用最新的 Eclipse (currently 2020-09) 和 OpenJDK Project Loom Early-Access Build

您可以通过直接从命令行编译和运行您的程序(使用javacjava 命令)来确保这是一个与Eclipse 相关的问题。

【讨论】:

    【解决方案2】:

    对于 ubuntu 系统: 在 .bashrc 文件中设置 java 16 路径。确保文件中只存在 java 16 路径。如果提到任何其他 java 路径,则以下命令可能不起作用。

    如果要确认java版本是否设置为16,则执行java -version
    然后您可以尝试通过以下命令直接编译您的织机类。

    javac className.java 
    

    java className
    

    它对我有用。

    【讨论】:

      【解决方案3】:

      即使您解决了编译问题,这可能也可能打印任何内容。

      虚拟线程需要carrier(要在其上执行的本机线程);如果本机线程完成得早于虚拟线程开始,则没有这样的载体;因此你没有打印。有几种方法可以解决这个问题。

      最简单的(只是为了看看它是否有效),就是让carrier 线程休眠一小会儿:

       Thread.startVirtualThread(() -> {
              while (true) {
                  System.out.println("trying " + Thread.currentThread().getName());
              }
          });
      
          LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(10));
      

      在我的机器上,这为生成一些输出提供了足够的时间。

      另一种方式是加入carrier

          Thread t = Thread.startVirtualThread(() -> {
               System.out.println("trying " + Thread.currentThread().getName());
          });
      
          t.join();
      

      这适用于演示目的,但在现实生活中您可能需要一个执行器。提供它的一种方法是通过:

         Thread.builder()
                .virtual(Executors.newFixedThreadPool(1))
                .task(() -> {
                    System.out.println("started");
                })
                .build()
                .start();
      
          System.out.println("done");
      

      您甚至可以使用 current 文档所述的Executors::newVirtualThreadExecutor

      创建一个执行器,为每个任务启动一个新的虚拟线程

      所以你可以做的是:

          ExecutorService service = Executors.newVirtualThreadExecutor();
      
          service.execute(() -> {
              System.out.println(Thread.currentThread().getId());
          });
      
          service.execute(() -> {
              System.out.println(Thread.currentThread().getId());
          });
      
          LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(10));
      

      【讨论】:

        猜你喜欢
        • 2020-12-01
        • 1970-01-01
        • 2020-02-01
        • 1970-01-01
        • 2021-12-13
        • 2022-11-09
        • 1970-01-01
        • 1970-01-01
        • 2013-05-23
        相关资源
        最近更新 更多