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来控制当前函数是否进入等待还是进入分配。存储。

    评论

报告相同问题?

悬赏问题

  • ¥15 python天天向上类似问题,但没有清零
  • ¥30 3天&7天&&15天&销量如何统计同一行
  • ¥30 帮我写一段可以读取LD2450数据并计算距离的Arduino代码
  • ¥15 C#调用python代码(python带有库)
  • ¥15 矩阵加法的规则是两个矩阵中对应位置的数的绝对值进行加和
  • ¥15 活动选择题。最多可以参加几个项目?
  • ¥15 飞机曲面部件如机翼,壁板等具体的孔位模型
  • ¥15 vs2019中数据导出问题
  • ¥20 云服务Linux系统TCP-MSS值修改?
  • ¥20 关于#单片机#的问题:项目:使用模拟iic与ov2640通讯环境:F407问题:读取的ID号总是0xff,自己调了调发现在读从机数据时,SDA线上并未有信号变化(语言-c语言)