Question about using virtual thread

Attila Kelemen attila.kelemen85 at gmail.com
Mon Jun 12 16:28:19 UTC 2023


>
>
> 1. When using per-request-per-virtual-thread style programming model, a
> general case would be to acquire a jdbc connection from some database
> connection pool, launch a SQL request, and then release the connection. I
> have some doubts that since database connections are usually a small
> number(like at most 100 connections), most of the virtual threads are
> waiting for them if requests come in quite fast. In this case, should I
> limit the number of virtual threads to reduce unnecessary waiting?
>
>
Most usually DB pool implementations can be limited in which case they will
just wait until one gets put back to the pool. So, that would work with
virtual threads and would provide a natural connection limit. Another way
is simply to use a semaphore, which would limit the number of concurrent DB
usage. Say, you could create a method like this for a pool (and always use
it instead of getting a connection by other means):

```
void withConnection(Consumer<? super Connection> action) {
  semaphore.acquire();
  try (var connection = getConnection()) {
    action.accept(connection);
  } finally {
    semaphore.release();
  }
}

and then call it like this:

```
pool.withConnection(connection -> {
  // Do something with connection
});
```


> 2. Is it recommended to create like several thousands of virtual threads,
> waiting to perform take() from a BlockingQueue infinitely? I noticed
> pooling virtual threads is definitely not recommended, so I am a
> little confused about this idea. which really sounds like pooling, but this
> mechanism can control the virtual threads concurrency pretty easily.
>
>
The benefit of virtual threads is that it is fine to create a virtual
thread that will start by blocking on a queue indefinitely (unlike with
normal threads, where it would be a horrible waste of resources), and then
processes the element (you still have to care about the case, when nothing
gets added to the queue anymore of course).



> 3. Sometimes a request may needs to perform a SQL request, sometimes not.
> I am wondering whether I should put the acquired database connection in a
> ThreadLocal or a ScopedValue. In old times, ThreadLocal would be perfect
> for this senario, however it seems that ScopedValue are preferred to be
> used in virtual threads. I noticed that the object that ScopedValue holds
> should remain unchanged during the method, but the unchanged object could
> have changable fields. So if when I receive a Http request, I create a
> object with a database connection field initialized as null, then when it
> needs to perform a SQL request, acquire a database connection and then put
> it into the ScopedValue's object, thus the later actions could all find it
> and use it from the ScopedValue.
> I don't know if it's recommended to use ScopedValue like this, which
> really looks like ThreadLocal.
>
>
Scoped values are still in preview, so you can't really use them in normal
production. But I think it would be better to use ScopedValue in the
future, because `StructuredTaskScope` automatically propagates them to
child threads (and I'm hoping we will get some other scope variants in the
future).

>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20230612/b121c77a/attachment.htm>


More information about the loom-dev mailing list