Golden_Dog 2015-07-16 15:59 采纳率: 0%
浏览 1726
已结题

tomcat4.1.40源码阅读HttpProcessor疑点求解?

1.首先:org.apache.catalina.connector.http.HttpConnector作为守护线程启动之

前,创建一个了Stack(org.apache.catalina.connector.http.HttpProcessor)用来准备

处理Socket。
HttpConnector的Start()方法:

 public void start() throws LifecycleException {

        // Validate and update our current state
        if (started)
            throw new LifecycleException
                (sm.getString("httpConnector.alreadyStarted"));
        threadName = "HttpConnector[" + port + "]";
        lifecycle.fireLifecycleEvent(START_EVENT, null);
        started = true;

        // Start our background thread
//--------------------启动HttpConnector run() begin----------------
        threadStart();//见下方run()方法
//--------------------启动HttpConnector run() end------------------
        // Create the specified minimum number of processors
        while (curProcessors < minProcessors) {
            if ((maxProcessors > 0) && (curProcessors >= maxProcessors))
                break;
//------------------------创建线程池begin-------------------------
            HttpProcessor processor = newProcessor();//见下方
//------------------------创建线程池end------------------------------
            recycle(processor);
        }

    }

HttpConnector的run()方法

  public void run() {
        // Loop until we receive a shutdown command
        while (!stopped) {
       // Accept the next incoming connection from the server socket
            Socket socket = null;
            try {
                socket = serverSocket.accept();
                if (connectionTimeout > 0)
                    socket.setSoTimeout(connectionTimeout);
                socket.setTcpNoDelay(tcpNoDelay);
            } catch (AccessControlException ace) {
                log("socket accept security exception", ace);
                continue;
            } catch (IOException e) {
                try {
                    //If reopening fails, exit
                    synchronized (threadSync) {
                        if (started && !stopped)
                            log("accept error: ", e);
                        if (!stopped) {osing server socket");
                            serverSocket.close();
                            serverSocket = open();
                        }
                    }
                } catch (IOException ioe) {
                    log("socket reopen, io problem: ", ioe);
                    break;
                } catch (KeyStoreException kse) {
                    log("socket reopen, keystore problem: ", kse);
                    break;
                } catch (NoSuchAlgorithmException nsae) {
             log("socket reopen, keystore algorithm problem: ", nsae);
                    break;
                } catch (CertificateException ce) {
                    log("socket reopen, certificate problem: ", ce);
                    break;
                } catch (UnrecoverableKeyException uke) {
                    log("socket reopen, unrecoverable key: ", uke);
                    break;
                } catch (KeyManagementException kme) {
              log("socket reopen, key management problem: ", kme);
                    break;
                }

                continue;
            }
            // Hand this socket off to an appropriate processor
            HttpProcessor processor = createProcessor();
            if (processor == null) {
                try {
                    log(sm.getString("httpConnector.noProcessor"));
                    socket.close();
                } catch (IOException e) {
                    ;
                }
                continue;
            }
//触发条件启动org.apache.catalina.connector.http.HttpProcessor begin
            processor.assign(socket);//见下方assign方法
//触发条件启动org.apache.catalina.connector.http.HttpProcessor end
            // The processor will recycle itself when it finishes

        }

   // Notify the threadStop() method that we have shut ourselves down
        synchronized (threadSync) {
            threadSync.notifyAll();
        }

    }

newProcessor()方法:

 private HttpProcessor newProcessor() {

        //        if (debug >= 2)
        //            log("newProcessor: Creating new processor");
        HttpProcessor processor = new HttpProcessor(this, curProcessors++);
        if (processor instanceof Lifecycle) {
            try {
                ((Lifecycle) processor).start();
            } catch (LifecycleException e) {
                log("newProcessor", e);
                return (null);
            }
        }
        created.addElement(processor);
        return (processor);

    }

HttpProcessor的assign(Socket socket)方法:

 synchronized void assign(Socket socket) {
//----------------问题所在地 begin-----------------
        // Wait for the Processor to get the previous Socket
        while (available) {
            try {
                wait();
            } catch (InterruptedException e) {
            }
        }
//----------------问题所在地 end-----------------
        // 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");

    }

2.问题:我理解:明明在run()方法中,每个socket请求都会对应从professor池子里面找一个新的HttpProcessor出来。此时该HttpProcessor既然已经在池子里就一定是available=false的。那么就不可能在assign方法中出现available=true的情况。如果真是这样那么这段代码不就没有意义了么?还是我的理解有问题?

在HttpProcessor中有可能出现available=true然后又在assign()方法中接收socket的情况吗?


源码贴不上来,有需要可以邮件发送该tomcat对应完整源码

  • 写回答

4条回答 默认 最新

  • oyljerry 2015-07-16 23:50
    关注

    多线程同步等情况,通过availbale来控制当前函数是否进入等待还是进入分配。存储。

    评论

报告相同问题?

悬赏问题

  • ¥50 导入文件到网吧的电脑并且在重启之后不会被恢复
  • ¥15 (希望可以解决问题)ma和mb文件无法正常打开,打开后是空白,但是有正常内存占用,但可以在打开Maya应用程序后打开场景ma和mb格式。
  • ¥20 ML307A在使用AT命令连接EMQX平台的MQTT时被拒绝
  • ¥20 腾讯企业邮箱邮件可以恢复么
  • ¥15 有人知道怎么将自己的迁移策略布到edgecloudsim上使用吗?
  • ¥15 错误 LNK2001 无法解析的外部符号
  • ¥50 安装pyaudiokits失败
  • ¥15 计组这些题应该咋做呀
  • ¥60 更换迈创SOL6M4AE卡的时候,驱动要重新装才能使用,怎么解决?
  • ¥15 让node服务器有自动加载文件的功能