`
Josh_Persistence
  • 浏览: 1649998 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类

Tomcat中的线程池(APR和ThreadPool)

阅读更多

一、容器简化了程序员自身的多线程编程。

        各种Web容器,如Tomcat,Resion,Jetty等都有自己的线程池(可在配置文件中配置),所以在客户端进行请求调用的时候,程序员不用针对Client的每一次请求,都新建一个线程。而容器会自动分配线程池中的线程,提高访问速度。

 

二、Tomcat线程池实现:

1、使用APR的Pool技术,使用了JNI。

Tomcat从5.5.17开始,为了提高响应速度和效率,使用了Apache Portable Runtime(APR)作为最底层,使用了APR中包含Socket、缓冲池等多种技术,性能也提高了。APR也是Apache HTTPD的最底层。

 

2、使用Java实现的Thread Pool。

      ThreadPool默认创建了5个线程,保存在一个200维的线程数组中,创建时就启动了这些线程,当然在没有请求时,它们都处理“等待”状态(其实就是一个while循环,不停的等待notify)。如果有请求时,空闲线程会被唤醒执行用户的请求。

      具体的请求过程是: 服务启动时,创建一个一维线程数组(maxThread=200个),并创建空闲线程(minSpareThreads=5个)随时等待用户请求。 当有用户请求时,调用 threadpool.runIt(ThreadPoolRunnable)方法,将一个需要执行的实例传给ThreadPool中。其中用户需要执行的 实例必须实现ThreadPoolRunnable接口。 ThreadPool 首先查找空闲的线程,如果有则用它运行要执行的ThreadPoolRunnable;

      如果没有空闲线程并且没有超过maxThreads,就一次性创建 minSpareThreads个空闲线程;如果已经超过了maxThreads了,就等待空闲线程了。总之,要找到空闲的线程,以便用它执行实例。找到后,将该线程从线程数组中移走。 接着唤醒已经找到的空闲线程,用它运行执行实例(ThreadPoolRunnable)。 运行完ThreadPoolRunnable后,就将该线程重新放到线程数组中,作为空闲线程供后续使用。

        由此可以看出,Tomcat的线程池实现是比较简单的,ThreadPool.java也只有840行代码。用一个一维数组保存空闲的线程,每次以一个较小步伐(5个)创建空闲线程并放到线程池中。使用时从数组中移走空闲的线程,用完后,再“归还”给线程池

      

总结: 

         tomcat5.5.10以上版本开始支持apr,支持通过apache runtime module进行JNI调用,使用本地代码来加速网络处理。

       如果不使用apr之前,Tomcat的Servlet线程池使用的是阻塞IO的模式,使用apr之后,线程池变成了 NIO的非阻塞模式,而且这种NIO还是使用了操作系统的本地代码,看tomcat文档上面的说法是,极大提升web处理能力,不再需要专门放一个web server处理静态页面了。
       我自己直观的感受是,不用apr之前,你配置多少个等待线程,tomcat就会启动多少个线程挂起等待,使用apr以后,不管你配置多少,就只有几个NIO调度的线程,这一点你可以通过kill -3 PID,然后察看log得知。

       假设不使用apr,可能端口的线程调度能力比较差,所以通过iptables进行端口转发,让两个端口去分担一个端口的线程调度,就有可能减少线程调度的并发,从而提高处理能力,减少资源消耗。

 

三、配置Tomcat线程池以使用高并发连接

1.打开共享的线程池:

<Service name="Catalina"> 
  <!--The connectors can use a shared executor, you can define one or more named thread pools--> 
 
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"   
    maxThreads="1000" minSpareThreads="50" maxIdleTime="600000"/>

默认前后是注释<!-- -->掉的,去掉就可以了。

重要参数说明:

name共享线程池的名字。这是Connector为了共享线程池要引用的名字,该名字必须唯一。默认值:None;

namePrefix:在JVM上,每个运行线程都可以有一个name 字符串。这一属性为线程池中每个线程的name字符串设置了一个前缀,Tomcat将把线程号追加到这一前缀的后面。默认值:tomcat-exec-;

maxThreads:该线程池可以容纳的最大线程数。默认值:200;

maxIdleTimeTomcat关闭一个空闲线程之前,允许空闲线程持续的时间(以毫秒为单位)。只有当前活跃的线程数大于minSpareThread的值,才会关闭空闲线程。默认值:60000(一分钟)。

minSpareThreadsTomcat应该始终打开的最小不活跃线程数。默认值:25。

threadPriority:线程的等级。默认是Thread.NORM_PRIORITY

 

2. 在Connector中指定使用共享线程池:

<Connector executor="tomcatThreadPool"
           port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443"
           minProcessors="5"
           maxProcessors="75"
           acceptCount="1000"/>

 

重要参数说明:
executor:表示使用该参数值对应的线程池;

minProcessors:服务器启动时创建的处理请求的线程数;

maxProcessors:最大可以创建的处理请求的线程数;

acceptCount:指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理。

 

BTW:我测试了一下,由于每次请求不再需要重新分配线程,系统响应速度还是有很明显的改善的。

 

7
0
分享到:
评论
10 楼 Josh_Persistence 2015-08-01  
kujo 写道
onthewanying 写道
javatozhang 写道
不知道在什么地方使用,求指教!谢谢!

用在tomcat性能调优,一个tomcat默认能抗住200左右的并发,调优后貌似可以到500并发的样子。


请问,这里说的200并发,是tps吗?200个在线用户同时操作?

是的。
9 楼 kujo 2015-08-01  
onthewanying 写道
javatozhang 写道
不知道在什么地方使用,求指教!谢谢!

用在tomcat性能调优,一个tomcat默认能抗住200左右的并发,调优后貌似可以到500并发的样子。


请问,这里说的200并发,是tps吗?200个在线用户同时操作?
8 楼 javatozhang 2013-11-15  
Josh_Persistence 写道
我最多用过1000过并发。
mn_1127 写道
楼主,有没有测过一个tomcat最大能承载多少并发?


如何测试这1000个并发?求指点
7 楼 Josh_Persistence 2013-11-14  
我最多用过1000过并发。
mn_1127 写道
楼主,有没有测过一个tomcat最大能承载多少并发?

6 楼 mn_1127 2013-11-11  
楼主,有没有测过一个tomcat最大能承载多少并发?
5 楼 Josh_Persistence 2013-11-11  
zhangping2056 写道
请问楼主,等待空线程的最大等待时间怎么配置?如果超过了最大等待时间,系统将返回什么?

maxIdleTime。可以看看上面的解释。
4 楼 zhangping2056 2013-11-11  
请问楼主,等待空线程的最大等待时间怎么配置?如果超过了最大等待时间,系统将返回什么?
3 楼 Josh_Persistence 2013-11-11  
在Tomcat_Home目录下的conf目录下的server.xml中。
2 楼 onthewanying 2013-11-11  
javatozhang 写道
不知道在什么地方使用,求指教!谢谢!

用在tomcat性能调优,一个tomcat默认能抗住200左右的并发,调优后貌似可以到500并发的样子。
1 楼 javatozhang 2013-11-11  
不知道在什么地方使用,求指教!谢谢!

相关推荐

    Tomcat线程池实现简介

    Tomcat提供了两种线程池实现,一种是基于Apache Portable Runtime (APR)的Pool技术,另一种是纯Java实现的ThreadPool。本文主要探讨后者,即Java实现的线程池。 Java实现的线程池位于`tomcat-util.jar`中,初始化时...

    ThreadPool UML图

    在本篇内容中,我们将根据标题“ThreadPool UML图”和描述“线程池的架构UML图。可以利用架构UML更好的理解线程池的工作原理。此时可以更好的进行代码的运用。”以及提供的部分代码片段,来深入探讨线程池的相关知识...

    C#托管代码实现的线程池类库项目ThreadPool.zip

    它一开始就初始化了一定数量的线程,并通过ProcessQueuedItems方法保证异步执行进入池中的队列任务 这样在分配异步任务的时候,就省去了频繁去创建(new)一个线程 初始化线程池 添加线程操作 线程池事件 结束线程...

    Tomat研究之ThreadPool

    从给定的文件信息来看,文章深入探讨了Tomcat中的线程池(ThreadPool)机制,这是Tomcat服务器处理HTTP请求的核心部分之一。Tomcat的线程池与Apache的CommonThreadPool不同,它专为Tomcat设计,以高效地管理并分配...

    微软的线程池API ThreadPool

    - 使用`ThreadPool.SetMinThreads`和`ThreadPool.SetMaxThreads`方法可以调整线程池的最小和最大线程数,但这通常只在特殊情况下进行,因为线程池有其内部的智能管理机制。 在实际开发中,理解并熟练运用线程池API...

    VC++ 线程池(ThreadPool)实现

    // 关闭工作项和线程池 CloseThreadpoolWork(work); CloseThreadpool(pool); TeardownThreadpoolEnvironment(&environ); return 0; } ``` 在这个例子中,`WorkerFunction`是我们的工作函数,`main`函数负责...

    C++11 线程池 ThreadPool

    线程池(ThreadPool)是一种管理线程资源的有效方式,它在现代并发编程中扮演着至关重要的角色。线程池允许程序预先创建一组线程,而不是每次需要时都创建新的线程,这样可以减少线程的创建和销毁开销,提高系统效率...

    C# .net智能线程池 SmartThreadPool

    这个库在.NET框架中提供了一个替代默认线程池(System.Threading.ThreadPool)的选择,尤其适用于需要更精细控制线程池行为的应用场景。SmartThreadPool具有许多高级特性,比如工作项优先级、自定义线程优先级、线程...

    c# 线程池的管理 通过ThreadPool

    C#中的线程池是一种高效的线程管理机制,它由.NET框架提供,旨在优化系统资源的使用,提高多线程程序的性能。...在实践中,结合异步编程模型(如`async/await`关键字)和线程池可以构建出更高效、更健壮的并发应用。

    线程池threadpool_src

    在“线程池threadpool_src”中,我们可以看到两个主要的文件:“www.pudn.com.txt”和“ThreadPoolApp”。虽然具体的内容无法在此提供,但根据文件名推测,“www.pudn.com.txt”可能包含与源代码相关的说明或者链接...

    ThreadPool 线程池管理单元

    ThreadPool 线程池管理单元 带调用例子

    线程池ThreadPool

    线程池ThreadPool。

    DELPHI的ThreadPool的线程池DEMO

    DELPHI的线程池(ThreadPool)是一种高效管理并发任务的技术,它允许程序在需要时创建线程,而不是每次需要执行任务时都手动创建。线程池通过预先创建一组线程,然后根据需要分配任务,减少了线程创建和销毁的开销,...

    python线程池threadpool实现篇

    线程池Threadpool实现篇中会涉及到以下术语和概念: 1. 工作线程(worker):线程池启动时创建指定数量的工作线程,这些线程主要负责从任务队列中获取任务并执行。 2. 任务(requests):任务是工作线程所处理的...

    C++11 ThreadPool:一个易于使用的C ++ 11线程池。-开源

    一个易于使用的C ++ 11线程池。 使用ThreadPool类对自由函数进行排队,并使用std :: for_each()和std :: transform()的并行版本。 可配置为仅用于标头或与库一起使用。 有许多用法示例。

    C++ 实现线程池ThreadPool

    线程池(ThreadPool)是多线程编程中的一个重要概念,它是一种线程使用模式,用于高效地管理和调度线程资源。在C++中实现线程池可以帮助开发者优化并发执行的任务,减少线程创建和销毁的开销,提高系统效率。下面...

    zl_threadpool, Linux平台下C (C 98、C 03、C 11)实现的线程池.zip

    《Linux平台下C语言实现线程池:zl_threadpool》 ...这个开源项目不仅是一个实用的工具,也是学习多线程编程和线程池设计的良好实例。通过阅读和理解其源码,开发者可以深入理解线程池的工作原理,提升自己的编程技能。

    java线程池threadpool简单使用源码

    Java线程池(ThreadPool)是Java并发编程中的一个重要概念,它可以帮助我们有效地管理和控制并发执行的任务,从而提高系统的效率和稳定性。线程池通过复用已存在的线程,避免了频繁创建和销毁线程带来的开销,同时也...

    threadpool 线程池 C语言版

    线程池在多线程编程中扮演着重要角色,它是一种高效的线程管理机制,能够有效地管理和调度系统中的线程资源。"threadpool 线程池 C语言版"是针对C语言实现的一种线程池模型,其核心在于任务队列和线程组的管理,以...

    线程池 threadpool

    在Windows API中,线程池被广泛使用,提供了诸如CreateThreadPool、CloseThreadPool、SetThreadpoolCallbackPool等函数来管理和操作线程池。在其他编程语言和平台中,如Java的ExecutorService或C#的ThreadPool,也有...

Global site tag (gtag.js) - Google Analytics