Question about using virtual thread

Ron Pressler ron.pressler at oracle.com
Mon Jun 12 19:18:01 UTC 2023



> On 12 Jun 2023, at 11:39, 刘希晨 <benrush0705 at gmail.com> wrote:
> 
> Hi I have several questions about using virtual threads in web application:
> 
> 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?

No, you should not. When a thread blocks waiting for something, behind the scenes you get the exact same queue you’d get if you tried to throttle manually, only easier to use. So just block and wait — that’s what virtual threads do best. Of course, depending on what percentage of the threads actually need to access the database (as opposed to getting their data from a cache) the database may become your bottleneck.

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

It’s impossible to create more or less virtual threads than you need. Every concurrent task in your application is represented by a virtual thread. It’s not that pooling virtual threads is not recommended, it’s that it cannot possibly ever improve anything, and it could make things work. You never, ever, pool virtual threads. EVER. 

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

Use whichever one you prefer. ScopedValues are not preferred for virtual threads; they’re preferred *always* in situations where their structured use fits their purpose. I wonder, though, why do you want to store the connection in the thread anyway. If you’re using a connection pool, you can just give it back and request again if you need to. If you do need to hold onto a connection for some reason, you probably need to close it or return it to the pool, so it sounds like somewhere in your thread you know when you’re done, which suggests that structured use would be possible, and if it’s possible — it’s preferable.

— Ron



More information about the loom-dev mailing list