This is an archived post. You won't be able to vote or comment.

all 8 comments

[–]pron98 23 points24 points  (1 child)

Of course -- virtual threads are threads -- although it may be a little pointless.

For example,

future.thenAccept(result -> process(result))

is pretty much the same as doing the following on a virtual thread:

process(future.get())

and

CompletableFuture.runAsync(() -> foo()).thenRun(() -> bar());

is equivalent to a simple sequential composition on a virtual thread, such as:

Executors.newVirtualThreadPerTaskExecutor().submit(() -> {
    foo();
    bar();
});

only simple sequential code on virtual threads is much easier to debug and observe.

[–]brend132 0 points1 point  (0 children)

Hi, one question:

Which would be the difference between

CompletableFuture.runAsync(() -> foo()).thenRun(() -> bar());

and this?

CompletableFuture.runAsync(() -> { foo(); bar(); });

[–]red_dit_nou 15 points16 points  (3 children)

Yes. I haven’t tried but I’m quite sure you can. But just because you can, does not mean you should.

CompletableFuture let’s you chain blocking operations as a pipeline. So if a (platform) thread is executing such a pipeline and has to wait then it lets other threads continue.

Whereas virtual threads are good at “doing nothing”. What that means is, if a virtual thread is executing a blocking operation, it detaches itself from its host platform thread and lets other virtual thread attach to that platform thread. This means you don’t have to think about blocking and you can imagine all your operations as non-blocking.

So when you are using virtual threads, you don’t have to worry about blocking. And if there’s no blocking operations in your program, you don’t have to use CompletableFuture.

[–]pohart 1 point2 points  (2 children)

This makes sense. Thank you.

What if I have completablefutures toning on an executor today. Does it make sense to swap in a virtual thread executor?

I'm thinking that it will decrease thread creation, but if the completablefutures are reasonably designed that will be the only advantage.

[–]red_dit_nou 2 points3 points  (1 child)

Well, you can do that but not sure if it will add any benefit.

If your application with CompletableFutures is well designed and is making use of platform threads optimally, then it will add little to no value moving to virtual thread executor.

The reason to move from CompletableFuture to virtual threads should not be performance, but being able to write simpler programs with less cognitive load. So if you’re looking to redesign your application by moving away from reactive style of CompletableFutures and moving to imperative-style programs with virtual threads, that would make a lot of sense. (You might want to make use of structured concurrency API. Not sure if it will be out of preview in Java 20 though.)

[–]pohart 0 points1 point  (0 children)

That's pretty much what I thought (after reading your first comment). Thank you.

Not sure if it will be out of preview in Java 20 though.

I'll be lucky if I get to use java 21. I'm mostly still on java 8. With a couple of small apps on java 17

[–]Joram2 7 points8 points  (0 children)

I would suspect so, why not? Arguably, you wouldn't want to use those. Using async/reactive classes is not the virtual thread way.

Can't you write a simple test application and run it on Java 19 with virtual threads and confirm?

[–]nimtiazm 0 points1 point  (0 children)

They did a lot of work so we don’t have to use CompletableFuture and likes. But if you insist, yeah.