On 23/12/2025 21:58, Attila Kelemen wrote:
Holo's response is probably your best bet for STS. Otherwise, Alan alluded to an implementation like this (disclaimer: I just typed it into an email, did no testing in anyway):

```
ThreadFactory limitedFactory(int limit, ThreadFactory wrapped) {
    var semaphore = new Semaphore(limit);
    return r -> {
        var thread = wrapped.newThread(() -> {
            try {
                r.run();
            } finally {
                semaphore.release();
            }
        });
        semaphore.acquireUninterruptibly();
        return thread;
    };
}
```

but as I noted previously, this has the problem that no API makes a general promise that a thread will actually be started.

If you move the acquire into the wrapped task then it will be closer to some of the sketches in previous discussions here. That would avoid the main task blocking in newThread, and goes to your comment about creating but not starting threads too.  There may be > limit Threads but at most min(limit, #ncores) would execute concurrently. Using acquire rather than acquireUninterruptibly, and handling the InterruptedException, would make also make it more responsive when the scope is cancelled before some of these subtasks run.

Zooming out a bit. With thread pools the maximum number of threads limits concurrency. If the maximum number of threads is less than other limits (DB connections, max number of network connections, etc.) then it removes/hides the need to have to configure limits on these resources. With virtual threads, which STS uses by default, then the limit on the number threads is effectively removed to allow for higher concurrency. To take advantage might mean configuring limits elsewhere which to more fine grain limiting of concurrency. Hopefully in time there will be more focus put on more finer grain limits rather than going back to limiting the number of threads.

-Alan


Reply via email to