2010-09-28 130 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容器中創建自己的線程會造成麻煩。 (可能有些情況下你必須這樣做,但是如果你有一些框架可以爲你管理線程,那麼你應該使用它。)