我的想法是这样的,在Servlet的doGet方法中开启一个新的线程,向客户端打印字符串。但是奇怪的现象发生了。先附上代码,很简单:
===========Servlet的代码=================
@WebServlet(name="secondServlet",urlPatterns="/second.do",asyncSupported=false)
public class SecondServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

PrintWriter out = resp.getWriter() ;

out.println("servlet begin .... " + System.currentTimeMillis()+"<br/>");
out.flush() ;

// AsyncContext context = req.startAsync(req , resp) ;
// new MyThread(context).start() ;
Thread t = new MyThread(resp.getWriter());
t.start() ;
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
out.println("servlet end .... " + System.currentTimeMillis()+"<br/>");
out.flush() ;
// out.close() ;
System.out.println(t.isAlive() ? "alive" : "no!");
}
}
=================MyThread的代码====================
public class MyThread extends Thread {// private AsyncContext context;
PrintWriter out = null ;// public MyThread(AsyncContext cxt) {
// this.context = cxt;
// }
public MyThread(PrintWriter out){
this.out = out ;
} @Override
public void run() {
try {
System.out.println("Thread begin"+System.currentTimeMillis());
// PrintWriter out = context.getResponse().getWriter() ;
out.println("Thread begin ..." + System.currentTimeMillis()+"<br/>");
out.flush(); Thread.sleep(3000); out.println("Thread end .... " + System.currentTimeMillis()+"<br/>");
out.flush();

System.out.println("Thread end"+System.currentTimeMillis());
out.close() ;
// context.complete() ;
} catch (InterruptedException e) {
e.printStackTrace();

}}
========================================
运行结果:
首先在控制台打印如下信息:
Thread start1344526355829
alive
然后在页面显示如下信息:
servlet begin .... 1344526355829
Thread begin ...1344526355829
servlet end .... 1344526356836
然后在控制台显示如下信息:
Thread stop1344526358834
========================================
然后!奇怪的问题来了,当我再次刷新页面时,控制台显示:
Thread start1344526462886
alive
Thread stop1344526465899
然后页面一片空白,响应结束。
我比较疑惑的是页面为什么会空白?我对http的这种请求响应机制理解的不深刻,求解释。

解决方案 »

  1.   

    Servlet运行完毕,与客户端的网络连接就会被自动断开,Writer同时会被自动关闭。所以要么你就得让Servlet永远不能结束,这样会占用线程,不过跟你重新启动一个线程也没啥区别。
    请参考下这个Blog:
    http://blog.csdn.net/ldh911/article/details/7268879
      

  2.   

    看到的页面是servlet生成的页面,当servlet的doget()或doPost()方法执行完毕,此刻页面内容是这时servlet中out所输出的。虽然你的线程仍在运行但是Servlet已经运行完了,至于你所得到的页面是空白是因为你代码中out.flush() ;把out清空了,你可以把这句注掉看一下效果
      

  3.   


    其实#1楼说的是对的。
    out.close(); 你希望是再Thread的run结束后再执行,
    但你的doGet执行(即使Thread没执行完)完了,java那里会不定时(不确定过多久),
    把out给关了。所以有时碰巧关完了,你还能打印出来不少。
    有时早关了,就一片空白了。