被Chrome的高级特性折腾了一上午

早上起来修改了一个小程序,使用Jetty嵌入的方式写了一个Servlet。因为第一次使用Jetty,不太熟悉对Servlet的多线程的处理方式。写了一个简单的测试代码:

protected void doGet(HttpServletRequest request, HttpServletResponse response)
	throws ServletException, IOException {
		//log.info("process thread:" + Thread.currentThread().getId() + "\tname:" + Thread.currentThread().getName());
		log.info("process thread:" + Thread.currentThread().getId() + "\tname:" + Thread.currentThread().getName());
		try{
			log.info("Sleep sevlet:" + this.hashCode());
			Thread.sleep(1000 * 20);
		}catch(Exception e){
			
		}
	}
Jetty的启动部分:
Server server = new Server(httpPort);
		System.out.println("Listening HTTP port:" + httpPort);
        ServletHandler handler=new ServletHandler();
        server.setHandler(handler);
        handler.addServletWithMapping("org.socialnet.servlet.StatusServlet", "/test1/*");
        handler.addServletWithMapping("org.socialnet.servlet.StatusServlet", "/test2/*");
			server.start();
	        server.join();
	        System.out.println("Shutdown HTTP service..");

  打开我的Chrome,在两个不同的标签页里面输入:

http://127.0.0.1:8081/test1,

按理说应该出现2个,“Sleep sevlet: xxx” 的信息。因为Sevlet是多线程的。 但是事实上并没有同时出现2个Sleep的线程。而是一个Sleep结束后,才出现另外一个Sleep servelt. 

这个时候可能很多人第一反应就是,Jetty的线程池大小不足,或者是单线程在处理请求。我觉得这种想法是合理的,本来Jetty就是轻量级的Server. 使用单线程来处理请求也没有什么不可以。为了验证这想法,修改了一下Jetty的启动部分:

Server server = new Server(httpPort);
		System.out.println("Listening HTTP port:" + httpPort);
        ServletHandler handler=new ServletHandler();
        server.setHandler(handler);
        handler.addServletWithMapping("org.socialnet.servlet.StatusServlet", "/test1/*");
        handler.addServletWithMapping("org.socialnet.servlet.StatusServlet", "/test2/*");
			server.start();
			log.info("thread:" + server.getThreadPool().getThreads() + 
					"\tidle:" + server.getThreadPool().getIdleThreads());
	        server.join();
	        System.out.println("Shutdown HTTP service..");
 

 输出活动线程的数量,果然和我期望一样,“thread:1  tidle:0” 只有一个服务线程启动了。马上google/ baidu 查询增加线程数量的方式。由于都要引入额外的包。我决定自己写一个简单的线程池,代码如下:

ThreadPool pool = new ThreadPool(){
			@Override
			public boolean dispatch(final Runnable arg0) {
				log.info
				new Thread(){
					public void run(){
						arg0.run();
					}
				}.start();
				return true;
			}
....
			};

对于每一个新的任务都启动一个新的线程,这下总可以了吧。 启动服务器。还是在多个标签窗口中刷新 " http://127.0.0.1:8081/test1" 还是没有按我期望的那样同时出现多个“Sleep servelt" 都是每隔20多秒出现一个"Sleep servelt" 感觉Sevlet就是在单线程运行一样。继续查看Jetty的API Doc.  说什么ServletHandler 不是完整的Sevelt的实现,有些限制,需要运行在Context里面才能是完整的Sevlet实现。 修改了代码

测试,还是如此。

后来试了以下在不同的标签打开:

http://127.0.0.1:8081/test1,

http://127.0.0.1:8081/test2,

这下出现了2个”Sleep servlt"了。但是无论我怎么增加线程,和在不同的标签页刷新,Sevelet总是串行的运行。实在是没有办法了,只好修改线程池,把运行的线程都输出看阻塞在什么地方了。最后发现一个问题,无论在多少个标签中刷新:

http://127.0.0.1:8081/test1。 都只会有一个TCP连接在线程池里面。原来Chrome对相同的URL,在不同 的标签打开只会连立一个连接。换成IE测试了一下,每次刷新都会出现一个新的Connection.

折腾了一上午,原来是Chrome的高级特性。

相关推荐