Not able us Virtual Threads using Project Loom

1.6k Views Asked by At

I was exploring the Virtual Threads in Project Loom. The Documents say it as straight forward with simple lines of code as below:

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

Or

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

I have tried both of them, For the first one, I receive an error The method startVirtualThread(() -> {}) is undefined for the type Thread

And for the second one - The method builder() is undefined for the type Thread

One browsing, found that lombok is required, Installed lombok as well. However it doesn't show up in Eclipse About section, I am able to use lombok, But still my issue is not resolved.

Below link show the documentation, I am referring to.

enter link description here

Sample Code:

 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();
    }
}

enter image description here

3

There are 3 best solutions below

0
Shay On

It looks like older versions of Eclipse is giving a compilation error when calling the new Thread methods related to Loom.

Please try to use the latest Eclipse (currently 2020-09) with an OpenJDK Project Loom Early-Access Build.

You can make sure that this is an Eclipse related issue by compiling and running your program directly from the command line (using javac and java commands).

0
Priyanka Thakur On

For ubuntu system: Set the java 16 path in .bashrc file. Make sure only have java 16 path present in the file. If any other java path is mentioned then following command may not work.

If you want to confirm if the java version is set to 16 then execute java -version.
Then you can try directly compile your loom class through following command.

javac className.java 

java className

It worked for me.

0
Eugene On

Even when you get the compilation problems go away, this might or might not print anything.

A virtual thread needs a carrier (a native thread to be executed on); and if the native thread finishes earlier then the virtual one starts, there is no such carrier; thus you get no printing. There are a couple of ways to work around that.

The simplest (just to see that this works), is to make the carrier threads sleep for a short while:

 Thread.startVirtualThread(() -> {
        while (true) {
            System.out.println("trying " + Thread.currentThread().getName());
        }
    });

    LockSupport.parkNanos(TimeUnit.MILLISECONDS.toNanos(10));

On my machine this gives enough time for some output to be generated.

Another way would be join on the carrier:

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

    t.join();

This works for demo purposes, but in real life you probably need an executor. One way to supply it would be via :

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

    System.out.println("done");

You can even use Executors::newVirtualThreadExecutor where the current documentation states:

Creates an Executor that starts a new virtual thread for each task

So what you could do, is something like:

    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));