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.
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.