[External] : Re: The default HttpServer Executor
Daniel Fuchs
daniel.fuchs at oracle.com
Wed May 14 11:24:39 UTC 2025
Hi Josiah,
On 13/05/2025 20:24, Josiah Noel wrote:
> The HttpServer doesn't use any default
> executor
>
>
> I know what you mean by this, but I have to point out that the class
> used is quite literally called DefaultExecutor
> <https://urldefense.com/v3/__https://github.com/openjdk/jdk/blob/e7ce661adb01fba4bb690d51cc2858c822008654/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java*L200-L204__;Iw!!ACWV5N9M2RV99hQ!JIfxp_rcxH9VkMOYILi4aLebtIM5Y9gOIT0jc3AgmPwkxmgz5lo2R7v9Q71TuUH5pHVtxuVS0pg5RjTkITf00A$>.>
> For backward compatibility I don't think we will ever
> change that default behaviour.
Oh - right - I see what you meant too then.
> Can you expand on this a little more? Is the backwards incompatibility
> that it would be able to serve more than a single request at the same time?
Yes. An application (handler's implementations) may depend on that.
> An executor can however be supplied to the HttpServer
> using `HttpServer.setExecutor` [1]
>
>
> After using this method for so long, I'm wondering if there is any
> reason that we have to go through this ceremony to serve more than one
> request at the same time. (Every time I've used it)
Probably to give control to the application over what kind
of executor it wants to use. There are many parameters there,
like should the threads be daemon? What should be the
Thread Context ClassLoader? What should be the thread names?
Should it be a pool executor, if so what should be the size
of the pool? No default choice would suit everybody.
Using a VirtualThreadPerTaskExecutor would eliminate most of
these questions, but virtual threads were not there when
the API was designed. IMO having a single thread was not an
unreasonable default, when there was an API to override
that and let the application provide the executor of its choice.
> Their might still be some side effect with using
> virtual thread however, especially if invoking code
> calling a native method that blocks, or loading a class
> that blocks in its static initializers.
>
>
> As you say, the default dispatcher currently runs serially, so if one
> does any sort of blocking operation, the dispatcher thread is pinned and
> cannot serve any more requests. If one were to switch to a virtual
> thread executor and call native blocking methods, is there a difference
> in this scenario? Either way, the server would be unable to serve
> requests while the thread is pinned by the blocking operation.
Blocking does not mean deadlocking, but if virtual threads get
pinned it can lead to carrier thread starvation: the code that
would "unblock" everything might never get executed because all
carrier threads are pinned.
best regards,
-- daniel
More information about the net-dev
mailing list