tomcat服务器解析(二) --- Endpoint

本文深入探讨了Tomcat服务器中的Endpoint组件,包括AbstractEndpoint的线程池和Acceptor,以及NioEndpoint的bind和startInternal过程。Endpoint初始化、启动过程中涉及的线程池创建、Acceptor和Poller线程的启动,特别是线程池如何处理Socket数据读写操作。通过分析,揭示了Endpoint在处理网络I/O和服务端连接中的核心作用。
Endpoint主要用来提供基础的网络I/O服务,封装了网络通讯相关的细节 。在AbstractProtocol中对Endpoint有这样一段注释
    /**
     * Endpoint that provides low  -  level network I/O  -  must be matched to the
     * ProtocolHandler implementation (ProtocolHandler using BIO, requires BIO
     * Endpoint etc.).
     */
     protected  AbstractEndpoint<S> endpoint =  null  ;


先对AbstractEndpoint( or g.apache.tomcat.util.net.AbstractEndpoint) 类做了解。


【AbstractEndpoint的线程池】
AbstractEndpoint有一个Executor的属性,是它所用的线程池。这个线程池可以是外界指定的,也可以是由AbstractEndpoint自己创建的。通过属性 internalExecutor 来标识使用的是外部的线程池,还是有Endpoint自己创建的线程池。

可以由外部调用显式指定endpoint使用的线程池
    /**
     * External Executor based thread pool.
     */
     private  Executor  executor  =  null ;
     public  void  setExecutor(Executor executor) {
         this . executor  = executor;
         this . internalExecutor  = (executor== null );
    }
     public  Executor getExecutor() {   return  executor  ; }

在当调用者没有显式指定所用线程池时,会创建一个自己所用的线程池,创建方法如下。
public  void  createExecutor () {
         internalExecutor  =  true  ;
        TaskQueue taskqueue =  new  TaskQueue();
        TaskThreadFactory tf =  new  TaskThreadFactory(getName() +  "-exec-"  ,  daemon  , getThreadPriority());
         executor  =  new  ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), 60, TimeUnit. SECONDS  ,taskqueue, tf);
        taskqueue.setParent( (ThreadPoolExecutor)  executor );
    }

【AbstractEndpoint的Acceptor】
在AbstractEndpoint中定义了Acceptor类(实现了Runnable接口),同时定义了acceptors属,主要用于接收网络请求。
    /**
     * Threads used to accept new connections and pass them to worker threads.
     */
     protected  Acceptor [] acceptors;

启动acceptors时,并没有使用前面提到过的线程池,而是生成了新的守护线程(getDaemon方法,默认返回true),来运行。但,具体在acceptors中线程的执行体,则交由具体的子类负责实现(貌似template-method模式是各种框架的基础配置),通过重写抽象方法createAcceptor来完成。

protected  final  void  startAcceptorThreads() {
         int  count = getAcceptorThreadCount();
         acceptors  =  new  Acceptor [count];

         for  ( int  i = 0; i < count; i++) {
             acceptors [i] = createAcceptor();
            String threadName = getName() +  "-Acceptor-"  + i;
             acceptors [i].setThreadName(threadName);
            Thread t =  new  Thread( acceptors  [i], threadName);
            t.setPriority(getAcceptorThreadPriority());
            t.setDaemon(getDaemon());
            t.start();
        }
    }

AbstractEndpoint框架主要定义了一些基本的属性,同时规定了生命周期的调用顺序。
Endpoint的初始化和启动,主要执行具体子类的所实现的startInternal方法来完成。

public  final  void  init()  throws  Exception {
         if  ( bindOnInit  ) {
            bind();
             bindState 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值