Questions on Build 18-loom+5-274 (2021/11/15)
Eric Kolotyluk
eric at kolotyluk.net
Tue Nov 23 21:55:45 UTC 2021
Yes, indeed, dropping in Virtual Threads to replace existing Platform
Threads is another key feature of Project Loom. Exploiting Structured
Concurrency involves some effort in redesign and refactoring for existing
projects, whereas I hope it would be the default for new designs and new
projects.
Agreed, switching the lexicon from Fibers to Virtual Threads to reuse the
Thread API was a marvelous insight. For me, what was old is now new again.
While I have a lot of experience with Reactive Systems, Functional
Non-Blocking practices did result in a lot of twisted thinking. Going back
to a more imperative style, being able to use Exceptions again, will make
future code more readable because we don't have to write non-blocking code
anymore. Blocking has now become cheaper or more affordable. Not that
functional style is bad, but it can be an overused strength.
Cheers, Eric
On Tue, Nov 23, 2021 at 1:38 PM Michael Bazos <mbazos at gmail.com> wrote:
> Thanks Eric,
> Yeah I totally agree but when dealing with existing code I really like how
> Executors.newVirtualThreadPerTaskExecutor() is like a drop-in replacement.
> I am assuming this was considered in the design and is important to have as
> there is lots of code in the Java ecosystem that allows you to set a custom
> Executor but you might not have access to plug-in a StructuedExecutor. I
> also think there will need to be some education about executors, I believe
> it's pretty well known that creating an executor service is an "expensive"
> operation, but when doing this with a virtual task executor it's considered
> "cheap".
>
> Assuming these features from an API perspective don't change dramatically
> upon release I see Executors.newVirtualThreadPerTaskExecutor() being used a
> lot immediately and then over time code authors and such will migrate to
> something like StructuedExecutor.
>
> I really like the approach loom has taken to use Executor and of course
> re-use Thread class. I imagine this was a lot more challenging up front but
> I am willing to bet that doing this will pay dividends in the future once
> this is released. We don't always get to work on new applications so having
> a pathway forward for older applications is very exciting.
>
> Mike
>
> On Tue, Nov 23, 2021 at 3:42 PM Eric Kolotyluk <eric at kolotyluk.net> wrote:
>
>> Mike, as I have discovered, StructuredExecutor.open() functions like
>> newVirtualThreadPerTaskExecutor(), one thread per task.
>>
>> While initially, I experimented with newVirtualThreadPerTaskExecutor(), I
>> now only use StructuredExecutor because it's a better solution.
>>
>> Cheers, Eric
>>
>> On Tue, Nov 23, 2021 at 12:26 PM Michael Bazos <mbazos at gmail.com> wrote:
>>
>>> Alan,
>>> Just wanted to let you know I took some high volume applications I work
>>> on
>>> that rely heavily on Executors and was easily able to switch to
>>> newVirtualThreadPerTaskExecutor and everything appears to be working
>>> well.
>>> Looking forward to the preview feature when it's ready.
>>>
>>> Mike
>>>
>>> On Fri, Nov 19, 2021 at 3:03 PM Alan Bateman <Alan.Bateman at oracle.com>
>>> wrote:
>>>
>>> > On 19/11/2021 19:15, Michael Bazos wrote:
>>> > > I started doing some experimenting with project loom an observed a
>>> few
>>> > > things and wasn't sure how to explain them or why it was happening:
>>> > >
>>> > > 1. I noticed when using
>>> Executors.newVirtualThreadPerTaskExecutor()
>>> > > submitting tasks and then calling 'shutdown()' on the executor
>>> > service, the
>>> > > virtual thread per task executor does not wait for tasks to
>>> finish.
>>> > This
>>> > > seems to behave a little differently than the OS based thread
>>> pool
>>> > > executors. I assume this is intended but just wanted to know why.
>>> > ExecutorService::shutdown is specified to not wait so the behavior you
>>> > observe is correct. You can use awaitTermination, or the new close
>>> > method, to wait for termination. Are you sure you've observed the
>>> > shutdown of other ExecutorService implementation wait, just curious.
>>> >
>>> > > 2. Playing with StructuredExecutor I can see the example of
>>> using it
>>> > > with try-with-resources which is clean and looks nice. I was
>>> > surprised to
>>> > > see `isShutdown()` as private on the StructuredExecutor. I am
>>> just
>>> > > wondering if a client didn't use try-with-resources there would
>>> be
>>> > some
>>> > > value in allowing a client to know if the executor is shutdown or
>>> > not. My
>>> > > best guess is the intention here is to minimize what is exposed
>>> from
>>> > the
>>> > > API.
>>> > If there is a case for exposing the state then it could be done.
>>> >
>>> >
>>> > > 3. My final question which is semi related to Question 2 I
>>> haven't
>>> > done
>>> > > any benchmarking myself yet but I know creating OS based executor
>>> > thread
>>> > > pools can be considered an "expensive" operation. Obviously this
>>> is
>>> > very
>>> > > different when doing this with virtual thread task executor. Does
>>> > using
>>> > > virtual thread task executor mean this is cheap to create and
>>> > shutdown?
>>> > > Typically in client code you wouldn't want to create/destroy task
>>> > executors
>>> > > during the lifecycle of an application.
>>> > The intention is that this should be very cheap to create and close.
>>> >
>>> > > Also I did some tests and I couldn't believe how many virtual
>>> threads I
>>> > > could spin up on my machine versus OS threads. Seems like memory
>>> would be
>>> > > the limit but the difference was ~3000 OS threads vs ~5 million+
>>> virtual
>>> > > threads.
>>> > >
>>> > > When I have time going to integrate the early loom builds into some
>>> real
>>> > > applications to see how it behaves. I very much look forward to not
>>> > having
>>> > > to worry about configuring thread pools in the future, very excited
>>> and
>>> > > keep up the good work!
>>> > >
>>> > Good, please let me know how you get on.
>>> >
>>> > -Alan
>>> >
>>>
>>
More information about the loom-dev
mailing list