一、容器简化了程序员自身的多线程编程。
各种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;
maxIdleTime:在Tomcat关闭一个空闲线程之前,允许空闲线程持续的时间(以毫秒为单位)。只有当前活跃的线程数大于minSpareThread的值,才会关闭空闲线程。默认值:60000(一分钟)。
minSpareThreads:Tomcat应该始终打开的最小不活跃线程数。默认值: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:我测试了一下,由于每次请求不再需要重新分配线程,系统响应速度还是有很明显的改善的。
相关推荐
Tomcat提供了两种线程池实现,一种是基于Apache Portable Runtime (APR)的Pool技术,另一种是纯Java实现的ThreadPool。本文主要探讨后者,即Java实现的线程池。 Java实现的线程池位于`tomcat-util.jar`中,初始化时...
在本篇内容中,我们将根据标题“ThreadPool UML图”和描述“线程池的架构UML图。可以利用架构UML更好的理解线程池的工作原理。此时可以更好的进行代码的运用。”以及提供的部分代码片段,来深入探讨线程池的相关知识...
它一开始就初始化了一定数量的线程,并通过ProcessQueuedItems方法保证异步执行进入池中的队列任务 这样在分配异步任务的时候,就省去了频繁去创建(new)一个线程 初始化线程池 添加线程操作 线程池事件 结束线程...
从给定的文件信息来看,文章深入探讨了Tomcat中的线程池(ThreadPool)机制,这是Tomcat服务器处理HTTP请求的核心部分之一。Tomcat的线程池与Apache的CommonThreadPool不同,它专为Tomcat设计,以高效地管理并分配...
- 使用`ThreadPool.SetMinThreads`和`ThreadPool.SetMaxThreads`方法可以调整线程池的最小和最大线程数,但这通常只在特殊情况下进行,因为线程池有其内部的智能管理机制。 在实际开发中,理解并熟练运用线程池API...
// 关闭工作项和线程池 CloseThreadpoolWork(work); CloseThreadpool(pool); TeardownThreadpoolEnvironment(&environ); return 0; } ``` 在这个例子中,`WorkerFunction`是我们的工作函数,`main`函数负责...
线程池(ThreadPool)是一种管理线程资源的有效方式,它在现代并发编程中扮演着至关重要的角色。线程池允许程序预先创建一组线程,而不是每次需要时都创建新的线程,这样可以减少线程的创建和销毁开销,提高系统效率...
这个库在.NET框架中提供了一个替代默认线程池(System.Threading.ThreadPool)的选择,尤其适用于需要更精细控制线程池行为的应用场景。SmartThreadPool具有许多高级特性,比如工作项优先级、自定义线程优先级、线程...
C#中的线程池是一种高效的线程管理机制,它由.NET框架提供,旨在优化系统资源的使用,提高多线程程序的性能。...在实践中,结合异步编程模型(如`async/await`关键字)和线程池可以构建出更高效、更健壮的并发应用。
在“线程池threadpool_src”中,我们可以看到两个主要的文件:“www.pudn.com.txt”和“ThreadPoolApp”。虽然具体的内容无法在此提供,但根据文件名推测,“www.pudn.com.txt”可能包含与源代码相关的说明或者链接...
ThreadPool 线程池管理单元 带调用例子
线程池ThreadPool。
DELPHI的线程池(ThreadPool)是一种高效管理并发任务的技术,它允许程序在需要时创建线程,而不是每次需要执行任务时都手动创建。线程池通过预先创建一组线程,然后根据需要分配任务,减少了线程创建和销毁的开销,...
线程池Threadpool实现篇中会涉及到以下术语和概念: 1. 工作线程(worker):线程池启动时创建指定数量的工作线程,这些线程主要负责从任务队列中获取任务并执行。 2. 任务(requests):任务是工作线程所处理的...
一个易于使用的C ++ 11线程池。 使用ThreadPool类对自由函数进行排队,并使用std :: for_each()和std :: transform()的并行版本。 可配置为仅用于标头或与库一起使用。 有许多用法示例。
线程池(ThreadPool)是多线程编程中的一个重要概念,它是一种线程使用模式,用于高效地管理和调度线程资源。在C++中实现线程池可以帮助开发者优化并发执行的任务,减少线程创建和销毁的开销,提高系统效率。下面...
《Linux平台下C语言实现线程池:zl_threadpool》 ...这个开源项目不仅是一个实用的工具,也是学习多线程编程和线程池设计的良好实例。通过阅读和理解其源码,开发者可以深入理解线程池的工作原理,提升自己的编程技能。
Java线程池(ThreadPool)是Java并发编程中的一个重要概念,它可以帮助我们有效地管理和控制并发执行的任务,从而提高系统的效率和稳定性。线程池通过复用已存在的线程,避免了频繁创建和销毁线程带来的开销,同时也...
线程池在多线程编程中扮演着重要角色,它是一种高效的线程管理机制,能够有效地管理和调度系统中的线程资源。"threadpool 线程池 C语言版"是针对C语言实现的一种线程池模型,其核心在于任务队列和线程组的管理,以...
在Windows API中,线程池被广泛使用,提供了诸如CreateThreadPool、CloseThreadPool、SetThreadpoolCallbackPool等函数来管理和操作线程池。在其他编程语言和平台中,如Java的ExecutorService或C#的ThreadPool,也有...