【问题标题】:How can we "disable" thread pooling in Jetty我们如何在 Jetty 中“禁用”线程池
【发布时间】:2021-10-31 12:12:15
【问题描述】:

是否可以将 Jetty Server 配置为不使用线程池,而是每次都创建/终止一个线程?起初我想创建一个简单的ThreadPool 类,但它看起来不像......

我们知道这对性能不是很好,我们正在接受它。

【问题讨论】:

  • 你尝试了什么?有一些代码或配置?
  • 我刚刚尝试了以下方法,并打算看看它是如何工作的... final ThreadPoolExecutor executor = new ThreadPoolExecutor(0, 200, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()) ; executor.allowCoreThreadTimeOut(true); final ExecutorThreadPool threadPool = new ExecutorThreadPool(executor); final Server jettyServer = new Server(threadPool);
  • Jetty ThreadPool 类基于 java.util.concurrent.Executor,这意味着适当的线程池以及适当的连接逻辑。你为什么要这样做?我问,因为也许有不同的方式来实现你的最终目标。
  • 无池线程执行器实际上会消耗更多内存并增加您的 GC 活动。我们通过一个实验性的 Jetty 11 分支进行了尝试,以更多地利用 JDK 17 loom 线程,体验在各方面都比传统的线程池差。

标签: java embedded-jetty


【解决方案1】:

提醒:Jetty 是一个 100% 异步服务器,绝对没有每 1 个请求 1 个线程的关系。单个请求每个请求使用 1..n 个线程是很常见的。每个请求的线程数取决于您所做的技术选择(协议选择、API 选择、Servlet 选择、第 3 方库选择等)。示例:在使用 Servlet 异步处理、Servlet 异步 I/O、HTTP/2 等时,您将使用更多线程...

这将是最小的“无池线程池”(一个可怕的概念,它实际上会消耗更多内存并将您的 GC 利用率提高几个数量级)。

下面的这个线程池实现是个坏主意。

请勿在生产服务器中使用

别说我没有警告过你。

这个线程池不符合java.util.concurrent.Executorjava.util.concurrent.ExecutorServicejava.util.concurrent.ThreadFactory 的基本原理,并且会导致随机组件出现问题:类加载器上下文、java SecurityManager 上下文、线程上下文、线程局部变量,并且可能会中断3rd 方集成,如 spring、jsp、security、jaas、jaspi、cdi、会话存储、会话持久性、ssl 参数、ssl 引擎状态等......

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

【讨论】:

  • 谢谢!了解“无池”的缺点,其中线程不仅用于请求处理,还用于许多其他可能的目的。我的最终目标是清理线程池中线程中无意残留的ThreadLocal,这是我们无法控制的。我的问题可能不是一个好问题...
  • 但无论如何,即使它不是用于生产用途,你的回答 NoThreadPool 对我来说很有趣。谢谢!
猜你喜欢
  • 1970-01-01
  • 2013-04-11
  • 2017-10-17
  • 2013-09-03
  • 1970-01-01
  • 1970-01-01
  • 2016-10-11
  • 2021-05-28
  • 1970-01-01
相关资源
最近更新 更多