Another virtual threads migration story: ReentrantReadWriteLock

Matthew Swift matthew.swift at gmail.com
Thu Jan 30 09:07:46 UTC 2025


Thanks for all the responses.

I'll respond to a couple of common themes in the responses:

* there is *no* contention on this lock. All threads have successfully
acquired the read lock. There are no writers and very unlikely to ever be
any writers in a production system
* RW locks are more defensive programming to ensure the application remains
functional in a non-production environment (dev/staging) when configuration
changes are made at run time. Use of RW locks for this purpose is a simple
design pattern, which is easy to understand and implement by any developer
* when runtime configuration changes can occur in production, I agree
alternative synchronization techniques should be used, which have been
proposed in this thread. Example use-cases include TLS key rotation,
service discovery events adjusting load-balancer config, etc
* this finding implies that RW locks cannot be used for simple
zero-contention defensive use-cases described above, at the moment anyway.
Conversely, I do expect virtual threads to be used in numbers greater than
64K, or I've been mis-sold :-)
* final point: sometimes it's not so easy to change the synchronization
implementation, such as when it is buried inside a third-party library.

I think I'll take the safest approach for now, bearing in mind the last
point above, which is to throttle the total number of concurrent requests
to 64K, which "ought to be enough for anybody" :-)

Thanks,
Matt


On Thu, 30 Jan 2025 at 02:47, David Holmes <david.holmes at oracle.com> wrote:

> On 30/01/2025 11:41 am, David Holmes wrote:
> > On 30/01/2025 4:20 am, Andrew Haley wrote:
> >> On 1/29/25 16:58, Matthew Swift wrote:
> >>>
> >>> Given that scaling IO to millions of concurrent IO bound tasks was
> >>> one of the key motivations for vthreads, it seems a bit surprising to
> >>> me that a basic concurrency building block of many applications is
> >>> constrained to 64K concurrent accesses. Are you aware of this
> >>> limitation and its implications?
> >>
> >>           * Lock state is logically divided into two unsigned shorts:
> >>           * The lower one representing the exclusive (writer) lock
> >> hold count,
> >>           * and the upper the shared (reader) hold count.
> >>
> >> I have no love at all for arbitrary limits, and this certainly sounds
> >> like
> >> one. And you may be right that these days it's something that might
> >> happen
> >> in real-world deployments.
> >
> > More of a practical limit than an "arbitrary" one.  Noone was going to
> > hit 64K contending platform threads. And requiring general 64-bit atomic
> > operations back when 32-bit was still very much mainstream, would not
> > have produced an efficient implementation.
> >
> >> Here's a suggestion: it shouldn't be madly difficult to rewrite the
> >> code so
> >> that instead of an int split into two unsigned shorts, it uses a long
> >> split
> >> into two unsigned ints. Why not give that a try, and see what happens?
> >> Building OpenJDK on most platforms is fairly straightforward these days.
> >
> > Simply rebasing to extend AbstractLongQueuedSynchronizer instead of AQS,
> > as others have suggested, may "just work".
>
> Though I meant to add that I think you will run into other scalability
> issues once you are dealing with such large numbers of threads.
>
> David
> -----
>
> > Cheers,
> > David
> >
> >> Once you have some information about how well it works in practice, it
> >> may
> >> be appropriate to talk to Doug Lea, the author, about removing the
> >> limitation.
> >>
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/loom-dev/attachments/20250130/035af00f/attachment-0001.htm>


More information about the loom-dev mailing list