Tomcat源码分析(三)------ 可携带状态的线程池
来源:互联网 发布:好看电影推荐 知乎 编辑:程序博客网 时间:2024/06/11 13:27
摘自http://blog.csdn.net/cutesource/article/details/5081916
最近想实现一个可携带状态的线程池,具体需求就是池中的线程被用来处理某种信息,而此信息可视为线程所依赖的外部状态。如果用简单的线程池来实现,线程初始化时就得赋予某些信息,使得线程无法被再次利用。在看老版Tomcat的源码时,找到了答案,其实现思路主要是利用了线程的等待和唤起,HttpProcessor的实现正好基于此思路,时序图如下所示:
初始化HttpProcessor线程时,没法赋予所需的Socket对象,因为如果在初始化阶段就赋予Socket会导致此线程没法回收用来处理其他Socket。因此,在HttpProcessor的run阶段,先把线程给wait住,具体在await方法里体现,代码如下所示:
- /**
- * Await a newly assigned Socket from our Connector, or <code>null</code>
- * if we are supposed to shut down.
- */
- private synchronized Socket await() {
- // Wait for the Connector to provide a new Socket
- while (!available) {
- try {
- wait();
- } catch (InterruptedException e) {
- }
- }
- // Notify the Connector that we have received this Socket
- Socket socket = this.socket;
- available = false;
- notifyAll();
- if ((debug >= 1) && (socket != null))
- log(" The incoming request has been awaited");
- return (socket);
- }
当HttpConnector调用HttpProcessor.assign(socket)方法时,会给此线程赋予Socket对象,并唤起此线程,使其继续执行,assign方法的源码如下所示:
- /**
- * Process an incoming TCP/IP connection on the specified socket. Any
- * exception that occurs during processing must be logged and swallowed.
- * <b>NOTE</b>: This method is called from our Connector's thread. We
- * must assign it to our own thread so that multiple simultaneous
- * requests can be handled.
- *
- * @param socket TCP socket to process
- */
- synchronized void assign(Socket socket) {
- // Wait for the Processor to get the previous Socket
- while (available) {
- try {
- wait();
- } catch (InterruptedException e) {
- }
- }
- // Store the newly available Socket and notify our thread
- this.socket = socket;
- available = true;
- notifyAll();
- if ((debug >= 1) && (socket != null))
- log(" An incoming request is being assigned");
- }
线程被唤起和赋予socket对象后,继续执行核心的process方法,HttpProcessor.run的完整源码如下所示:
- /**
- * The background thread that listens for incoming TCP/IP connections and
- * hands them off to an appropriate processor.
- */
- public void run() {
- // Process requests until we receive a shutdown signal
- while (!stopped) {
- // Wait for the next socket to be assigned
- Socket socket = await();
- if (socket == null)
- continue;
- // Process the request from this socket
- try {
- process(socket);
- } catch (Throwable t) {
- log("process.invoke", t);
- }
- // Finish up this request
- connector.recycle(this);
- }
- // Tell threadStop() we have shut ourselves down successfully
- synchronized (threadSync) {
- threadSync.notifyAll();
- }
- }
0 0
- Tomcat源码分析(三)------ 可携带状态的线程池
- Tomcat源码分析(三)------ 可携带状态的线程池
- Tomcat源码分析(三)------ 可携带状态的线程池
- Tomcat源码分析(三)------ 可携带状态的线程池 .
- Tomcat源码分析(三)------ 可携带状态的线程池
- Tomcat源码分析之三_ 可携带状态的线程池
- Tomcat源码分析-线程池应用
- tomcat源码分析学习笔记(三)
- 线程的状态分析
- java之多线程(三)线程的状态
- 第二人生的源码分析(四十三)虚拟文件系统线程
- tomcat源码解读三(2) tomcat中JMX的源码分析
- Tomcat源码分析(三)------ Request和Response处理的全过程
- Hessian源码分析和Hack --让Hessian携带远程调用端的信息
- tomcat的启动过程(Tomcat源码解析(三))
- tomcat的启动过程(Tomcat源码解析(三))
- android 线程池的源码分析
- muduo源码分析--线程池的实现
- python与zmq系列(5)
- 模拟一个A标签,避免被浏览器拦截
- Android 4.4从图库选择图片,获取图片路径并裁剪
- CodeForces 253A Boys and Girls
- java对象的序列化与反序列化
- Tomcat源码分析(三)------ 可携带状态的线程池
- 【hibernate集锦】---hibernate缓存机制
- Address already in use - bind(二) (Errno:EADDRINUSE)
- Tomcat源码分析(四)------ Request和Response处理的全过程
- JAVA 创建TXT文件,写入文件内容,读取文件内容
- Java——Ajax+Tomcat完成异步请求
- 数据库操作(使用FMDB)
- NSPredicate 谓词
- 基于openfire+smack开发Android即时聊天应用[一]---openfire安装部署