2010-09-28 95 views
14

什么是对的servlet 3.0异步功能之间有多种不同的:的Servlet 3.0异步

old servlet impl 
doGet(request,response) { 
Thread t = new Thread(new Runnable() 
    void run(){ 
     // heavy processing 
     response.write(result) 
    } 
} 
t.start(); 

在servlet的,如果我浪费了线程做繁重的处理3.0 - 我赚一个多线程的容器,但我浪费在繁重的处理... :(

有人能帮忙吗?

+7

如果下面的任何答案都是你要找的,你能不能将其标记为这样? – 2011-08-03 11:28:45

回答

2

该Servlet 3.0异步功能提供了保持HTTP连接打开,但释放时,请求不能被立即送达任何未使用的线程,而是等待某些事件发生或例如当哟你正在编写一些彗星/反向ajax应用程序。在上面的例子中,你正在创建一个新的线程,所以除非你想让请求等待某个事件,否则它不应该对你有所帮助。

最好的问候, 凯沙夫

23

这是行不通的。一旦你的doGet方法结束,响应就完成并发送回客户端。你的线程可能还在运行,但它不能再改变响应。

Servlet 3.0中的新异步功能的作用是允许您释放请求线程以处理其他请求。什么情况如下:

RequestThread: |-- doGet() { startAsync() } // Thread free to do something else 
WorkerThread:     |-- do heavy processing --| 
OtherThread:           |-- send response --| 

重要的是,一旦RequestThread已通过调用启动异步处理startAsync(...),它是免费做别的事情。例如,它可以接受新的请求。这提高了吞吐量。

+0

据我的理解,'RequestThread'在调用'startAsync(...)'后不会'自由'做其他事情,只有在'RequestThread'完成它的工作时它才会是空闲的,例如,如果在doGet()中调用'startAsync(...)',执行'doGet()'后,RequestThread将会自由。 – user454322 2012-05-13 12:14:26

+0

准确地说,处理'doGet()'的线程将在整个方法堆栈完成后可用(调用方法的方法......调用调用'doGet() ')。 – 2012-05-13 13:11:43

+0

是的,这就是我的意思 – user454322 2012-05-13 13:59:53

2

有几个API支持COMET(长时间活着的HTTP请求,没有线程/请求问题)编程。所以没有严格的需要使用servlet 3 API来避免线程/请求。一个是在Glassfish 2.11(example)中运行的Grizzly引擎。第二种解决方案是Jetty Continuation。第三个是Servlet 3 API.

基本概念是请求创建一些容器管理的异步处理程序,其中请求可以订阅由对象标识的事件(例如clientid字符串)。然后,异步处理线程可以对处理程序说,该事件发生,请求获得一个线程继续。它完全取决于你可以使用的你选择的应用程序服务器。哪一个是你的选择?

+0

人们应该注意到Grizzly和Jetty各自通过他们自己的解决方法实现了这一点,而Servlet 3.0标准意味着不再需要这种不可移植(跨不同的应用程序服务器)解决方案。人们会想到,Grizzly和Jetty自然会(或将要)实现Servlet 3.0。所以,这不是三者之间的选择问题,而是选择实施第三者中哪一种,你喜欢。 – user359996 2010-10-14 04:45:57

2

在servlet容器中创建自己的线程会造成麻烦。 (可能有些情况下你必须这样做,但是如果你有一些框架可以为你管理线程,那么你应该使用它。)