Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use virtual threads with ScheduledExecutorService

I want to use virtual threads introduced in Java 19 and ScheduledExecutorService. I need to schedule some threads to be run every minute. I know that I can use something like this: ScheduledExecutorService executor = Executors.newScheduledThreadPool(100, Thread.ofVirtual().factory()); But it looks like I'm forced to set pool size.

I'm looking for a fabric method similar to this: ScheduledExecutorService executor = Executors.newScheduledThreadPool(Thread.ofVirtual().factory()); But I can't find it. I would like to follow "one virtual thread per task" principle and not be forced to set a fixed number of threads in the pool. Do you know if I can use ScheduledExecutorService in that way? Or some alternative exists which are adapted to virtual threads?

UPDATE

Let me elaborate on what problem I try to solve. So I need to create more than 1000 tasks (I don't know the exact number, I can only estimate it). Which should be run periodically. Some need to be run every minute, some every two minutes, etc.

Those tasks will perform I/O operations (network requests). So virtual threads look like a good choice. But I need some scheduling functionality to achieve it. By choosing ScheduledExecutorService I can use methods like: scheduledThreadPoolExecutor.scheduleAtFixedRate(runnableTask, 60, 60, TimeUnit.SECONDS )

If I would not need scheduling I would simply create an executor like that: var executor = Executors.newVirtualThreadPerTaskExecutor() But plain ExecutorService doesn't provide any scheduling functionality. And I would be forced to implement scheduling on my own.

So for now the best solution I found is: Executors.newScheduledThreadPool(1000, Thread.ofVirtual().factory()); This generally looks good but I wonder if some other solution in Java API exists which allows me to create ScheduledExecutor but I will not be forced to set the size of a thread pool. Which for me looks a little bit strange when we consider virtual threads.

like image 433
Piotrold Avatar asked Sep 13 '25 01:09

Piotrold


2 Answers

I think you want to consider offloading the work to virtual threads, and schedule the work with a sheduler.

ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor()
ExecutorService donkey = Executors.newVirtualThreadPerTaskExecutor()

Then when you want to schedule a task.

void schedule(Runnable command, long delay, TimeUnit unit){
    scheduler.schedule( ()->donkey.execute(command), delay, unit);
}

You really don't want your scheduling thread to be split up amongst virtual threads because you want your scheduling thread to be free to schedule more tasks.

like image 129
matt Avatar answered Sep 14 '25 15:09

matt


Executors.newScheduledThreadPool(0, Thread.ofVirtual().factory());
like image 27
JPG Avatar answered Sep 14 '25 14:09

JPG