【问题标题】:Threads generated in TomcatTomcat 中生成的线程
【发布时间】:2011-05-23 07:40:30
【问题描述】:

我有一个关于 Tomcat 线程创建的基本问题。每个浏览器实例是在单个线程上运行还是产生多个线程来处理单个浏览器实例请求?

我在代码中引用当前线程并调用 activecount 方法,它显示 20 表示 20 个活动线程。所以我怀疑这个值是从哪里配置的。是否有任何参数可以设置每个活动线程

while (iter.hasNext()) {
  GrammarSection agrammarSection= null;
  try {
    agrammarSection = (GrammarSection) iter.next();
  } catch (Exception e) {
    System.out.println("DDD if it come in exception "+Thread.currentThread());
    System.out.println("DDD if it come in exception "+Thread.activeCount()); //IT PRINTS 20

【问题讨论】:

  • 如果您使用 JConsole 或 JVisualVM 等工具,您将能够轻松(通过 GUI)查看活动线程并了解它们是什么。

标签: java tomcat


【解决方案1】:

Tomcat 创建一个线程池。通常,一个 HTTP 请求由一个线程处理。

【讨论】:

  • 感谢您的回复。但是,我对为什么 Thread.activeCount 返回值 20 有疑问。 activeCount 返回与当前线程的线程组关联的活动线程数。当我使用 main 方法运行一个独立的 java 程序时,activeCount 返回 1。
  • 所以我在这里有点困惑。我问这个问题的原因是我在我的应用程序中看到了一些异常,只有在为一个 http 请求执行多个线程时才会发生这种情况
  • 查看我的回复。另外还要注意,Tomcat 有“守护进程”/服务线程,与您的页面/servlet 没有直接关系。
【解决方案2】:

Tomcat(和大多数 servlet 容器)使用线程池。也就是说 - 它们预先初始化可配置数量的线程,并且每当请求到达服务器时,都会从池中取出一个线程并分配给处理请求。

【讨论】:

  • 谢谢...所以线程池中的多个线程可能同时运行以处理一个 HTTP 请求?
  • 没有。一个请求 = 一个线程。 (除非你从代码开始你自己的线程)
  • Tomcat 总是在池中拥有最少数量的“等待”线程,以及一些“服务”线程(例如检测您是否部署了新的 war 文件的侦听器等)。
【解决方案3】:

Tomcat 使用线程池,有关配置的简要概述,请参阅此链接:

Default Tomcat Connector Behaviour

响应“是否每个浏览器实例都在单个线程上运行?”答案是“取决于”:

返回文本等的单个 HTTP 请求将消耗一个接受者线程。

但是,如果您呈现的页面也包含图像(在同一服务器实例上)或者如果它使用框架,那么浏览器也会对它们发出请求(因为每个图像/页面都需要向服务器发出另一个 HTTP 请求)。

而且...以上内容与 HTTP 连接器线程有关。当然,您可以拥有一个多线程的 servlet(执行一些任意任务)。这不会计入上面配置中看到的“maxThreads”限制,但会显示为 JVM 中的活动线程。

【讨论】:

    【解决方案4】:

    一般来说确实不是。

    这里讨论的许多人谈到 1 个 HTTP 请求将由 1 个 Tomcat 线程提供服务。但你不应该认为 1 个页面只会触发 1 个 HTTP 请求。

    至少这取决于你使用的是哪个浏览器,1页中有多少资源,以及是否涉及AJAX,保持连接。

    (1) 一个浏览器实例将在浏览器/客户端生成多个线程来下载单个页面的资源,并将占用 Tomcat/Apache/Weblogic/Websphere/您使用的任何应用程序服务器上的多个线程。这是由于现代多线程浏览器的本质。如果您真的在谈论纯 HTML 页面,它可能只在 Tomcat 中生成 1 个(工作)线程,但是当您在页面中添加其他资源(例如图像)时,图像可能(并且很可能)将与页。浏览器通常不会等到整个页面加载完毕后再加载图像。当您使用诸如 FireBug 之类的工具(在网络部分)时,您可以清楚地看到这一点。页面不是按顺序加载的。

    (2)在AJAX应用中,一个页面也会触发服务器上的多个线程。

    (3) 还要考虑到 HTTP 1.1 协议(除非您仍在使用 HTTP 1.0)将保持连接直到 HTTP 超时。默认情况下它不会关闭连接。您需要查看 Tomcat/WAR 设置中的 Keep-Alive 参数。您可能需要在 Tomcat 前面添加一个反向代理(例如 Apache、nginx、Squid、Varnish)来卸载其中一些保持活动连接。

    【讨论】:

      猜你喜欢
      • 2016-03-24
      • 1970-01-01
      • 1970-01-01
      • 2014-11-13
      • 1970-01-01
      • 1970-01-01
      • 2011-07-11
      • 2012-11-29
      • 1970-01-01
      相关资源
      最近更新 更多