Search code examples
javaembedded-jetty

How can we "disable" thread pooling in Jetty


Can Jetty Server be configured not to pool threads, but to create/terminate a Thread every time? I at first thought to create a simple ThreadPool class, but it didn't look like...

We're aware that it's not very good for performance, and we are accepting it.


Solution

  • Reminder: Jetty is a 100% async server, there is absolutely NO relationship of 1 thread per 1 request. It is common for a single request to use 1..n threads per request. The number of threads per request is dictated on the technology choices you make (Protocol choices, API choices, Servlet choices, 3rd party library choices, etc). Example: you will use more threads when using things like Servlet Async Processing, Servlet Async I/O, HTTP/2, etc ...

    This would be the minimum "no pooling thread pool" (a horrid concept that will actually consume more memory and increase your GC utilization by several orders of magnitude).

    This thread pool implementation below is a bad idea.

    DO NOT USE IN A PRODUCTION SERVER

    Don't say I didn't warn you.

    This thread pool doesn't honor the fundamentals of java.util.concurrent.Executor, java.util.concurrent.ExecutorService and java.util.concurrent.ThreadFactory, and will cause issues in random components: classloader contexts, java SecurityManager contexts, thread contexts, Thread Locals, and will likely break 3rd party integraions like spring, jsp, security, jaas, jaspi, cdi, session storage, session persistence, ssl parameters, ssl engine state, etc ...

    import org.eclipse.jetty.util.component.AbstractLifeCycle;
    import org.eclipse.jetty.util.thread.ThreadPool;
    
    public class NoThreadPool extends AbstractLifeCycle implements ThreadPool
    {
        private final Object joinLock = new Object();
    
        @Override
        public void execute(Runnable command)
        {
            Thread thread = new Thread(command);
            thread.setName("NoThreadPool"); // name your thread, helps in debugging later
            thread.start();
        }
    
        @Override
        public void join() throws InterruptedException
        {
            synchronized (joinLock)
            {
                while (isRunning())
                {
                    joinLock.wait();
                }
            }
    
            while (isStopping())
            {
                Thread.sleep(50);
            }
        }
    
        @Override
        protected void doStop() throws Exception
        {
            super.doStop();
            synchronized (joinLock)
            {
                joinLock.notifyAll();
            }
        }
    
        @Override
        public int getThreads()
        {
            return 1; // this pool is always in use
        }
    
        @Override
        public int getIdleThreads()
        {
            return 100_000; // this pool always has capacity
        }
    
        @Override
        public boolean isLowOnThreads()
        {
            return false; // this pool is never low on threads
        }
    }