论坛首页 Java企业应用论坛

Tomcat连接器源码分析2

浏览 1951 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-04-09   最后修改:2011-04-09
接上篇http://www.iteye.com/topic/994833,
我们看到JioEndPoint的start方法有下面一段代码:
  // Create worker collection
  if (executor == null) {
      workers = new WorkerStack(maxThreads);
  }
在上一篇中,executor一直都为null。什么时候不为空呢,这里因为Server.xml文件里的Connector元素还有一个executor属性,它指向一个Executor属性的名字。(参考:
http://tomcat.apache.org/tomcat-6.0-doc/config/http.html)。
在连接器配置项的上方有一个默认的Executor元素:
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>
不过当前他是注释掉的,我们把他打开。
这个Executor默认的类是org.apache.catalina.core. StandardThreadExecutor,
当然你可以通过它的className属性使用自己的类,但必须像StandardThreadExecutor
一样实现Executor接口。

StandardThreadExecutor是在Doug lea大爷的ThreadPoolExecutor类构造出来的:
public void start() throws LifecycleException {
        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);
        TaskQueue taskqueue = new TaskQueue();
        TaskThreadFactory tf = new TaskThreadFactory(namePrefix);
        lifecycle.fireLifecycleEvent(START_EVENT, null);
        executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), maxIdleTime, TimeUnit.MILLISECONDS,taskqueue, tf) {
			@Override
			protected void afterExecute(Runnable r, Throwable t) {
				AtomicInteger atomic = submittedTasksCount;
				if(atomic!=null) {
					atomic.decrementAndGet();
				}
			}
        };
        taskqueue.setParent( (ThreadPoolExecutor) executor);
        submittedTasksCount = new AtomicInteger();
        lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
}


剩下的工作就是在Connector里添加属性executor,来引用tomcatThreadPool。
<Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
这样executor就横空出世。

那么开始那段代码就不需要WorkerStack了。Tomcat虽然自个搞了个WorkerStack出来,
但还是给Doug lea大爷一个面子哦。
这样processSocket不需大费周折,直接交给executor去执行就OK了:
protected boolean processSocket(Socket socket) {
        try {
            if (executor == null) {
                getWorkerThread().assign(socket);
            } else {
                executor.execute(new SocketProcessor(socket));
            }
        } catch (Throwable t) {
            // This means we got an OOM or similar creating a thread, or that
            // the pool and its queue are full
            log.error(sm.getString("endpoint.process.fail"), t);
            return false;
        }
        return true;
    }

论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics