Java for Web学习笔记(八):Servlet(6)doGet()和doPost()是线程还是队列

做一个小实验,代码如下:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    try{
        for(int i = 0 ;i < 10 ; i ++){
            Thread.sleep(1000);
            System.out.println(request.getRemoteAddr() + ":" + request.getRemotePort() + "------------[" + i +"]-------------");
        }
    }catch(Exception e){			
    }
}

在firefox中触发两次请求,结果发现是依次执行,难道会这么老土使用队列串行方式,而不是线程的并行方式。在firefox中触发一次请求,然后在浏览器中按“×”停止,重新在触发一次,这次我们看到的是并行执行。那么就是firefox依次发送请求。

为了进一步明确,开启了两个浏览器,IE和firefox,再次进行测试,明确doGet()是以线程的方式处理。

一般而言,web container维护某种线程池,一般称为connector pool或者executor pool。当一个请求到来时,从线程池中获取线程,如果没有,这放入FIFO的队列。在tomcat中这个队列有长度限制,称为acceptCount,如果到达这个限制,将会拒绝请求。在返回reponse给client后,向线程池退还该线程。

创建一个线程和销毁一个线程需要的处理量较大,因此不采用收到某个请求就为该请求建立一个处理线程的方式。采用线程池,重利用线程,从而提高web container的处理性能。地址池大小受到具体硬件配置的限制。Tomcat的缺省值为200线程。

在log4j2中,查看使用线程的名字,可以用%t。

多线程,就会有同步问题。例子如下:

private volatile int TICKET_ID_SEQUENCE = 1;
private Map<Integer, Ticket> ticketDatabase = new LinkedHashMap<>();

private void methodOne(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
    //… …

    int id;
    synchronized(this){
    	id = this.TICKET_ID_SEQUENCE++;
        // 因为LinkedHashMap和先后顺序有关的,所以放在同步锁里面,如果是一般的Map,无需如此。
    	this.ticketDatabase.put(id, ticket); 
    }

    //… …
}


相关链接: 我的Professional Java for Web Applications相关文章

你可能感兴趣的:(Java for Web学习笔记(八):Servlet(6)doGet()和doPost()是线程还是队列)