2011-08-03 93 views
15

,我讀了類似Q &一個設計模式來處理異步響應在Java中

How do you create an asynchronous HTTP request in JAVA?解答| Asynchronous programming design pattern |
AsyncTask Android - Design Pattern and Return Values

我看到很多解決方案,但沒有真正滿足我的需求。

偵聽方式

一旦結果被發現,則處理在onResult方法實現。

public interface GeolocationListener { 
public void onResult(Address[] addresses); 
public void onError(Exception e); 
} 

這種解決方案並不十分satify我,因爲我要處理的主要方法的結果。我討厭這個接口,因爲當返回響應時,它會在onResult中處理,導致處理鏈,無法返回到「main」方法。

該servlet方式

public class SignGuestbookServlet extends HttpServlet { 

    public void doPost(HttpServletRequest req, HttpServletResponse resp) 
       throws IOException { 
     // ... 
     resp.sendRedirect("/guestbook.jsp"); 
    } 
} 

沒有暴露的Java代碼調用這個servlet。所有的配置在web.xml

做我想

等待這樣

Response a = getResponse(); 
// wait until the response is received, do not go further 
// process 
Response b = getResponse(); 
// wait until the response is received, do not go further 
process(a,b); 

響應的方法是有一個設計模式來處理異步請求,並等待像上面那樣的迴應?除了聽衆以外的其他方式。 請不要圖書館或框架。

編輯 由於到目前爲止的反應。我沒有給你完整的圖片,所以我公開了Geolocation類 我開始實施。我不知道如何實施該方法。有人可以顯示「如何」?他(或她)還必須實現監聽器如果你想在一個Web應用程序頁面流檢索結果

private Address getFullAddress (String text, AddressListener listener, ...){ 

    // new Geolocation(text, listener, options).start() 
    // implements Geolocation.GeolocationListener 
    // how to return the Address from the onResult ? 
} 
+0

你問你在編輯是離題。而且這個語氣非常專橫。 – toto2

+0

對不起,我並不打算成爲專橫的。只是提供了關於getResponse應該返回並實現偵聽器的更多信息。您的答案提供了一個新的解決方案,但對我來說太短(沒有與聽衆一起實施)將其標記爲接受的答案。 –

+0

@raymondchenon真的,怎麼做這樣的事情:私有地址getFullAddress(字符串文本,AddressListener監聽器,...){---------對於另一個樣品,在使用我們凌空庫,實例化JsonObjectRequest時,它有覆蓋onResponse和onError。 –

回答

9

異步代碼始終可以同步。最簡單/最簡單的方法是進行異步調用,然後輸入一個while循環,它只是休眠當前線程,直到值返回。

編輯:,輪流異步回調到同步碼碼 - 再次,原油實現:

import java.util.concurrent.*; 

public class MakeAsynchronousCodeSynchronous { 
    public static void main(String[] args) throws Exception { 
     final Listener listener = new Listener(); 
     Runnable delayedTask = new Runnable() { 
      @Override 
      public void run() { 
       try { 
        Thread.sleep(2000); 
       } catch (InterruptedException e) { 
        throw new IllegalStateException("Shouldn't be interrupted", e); 
       } 
       listener.onResult(123); 

      } 
     }; 
     System.out.println(System.currentTimeMillis() + ": Starting task"); 
     Executors.newSingleThreadExecutor().submit(delayedTask); 
     System.out.println(System.currentTimeMillis() + ": Waiting for task to finish"); 
     while (!listener.isDone()) { 
      Thread.sleep(100); 
     } 
     System.out.println(System.currentTimeMillis() + ": Task finished; result=" + listener.getResult()); 
    } 

    private static class Listener { 
     private Integer result; 
     private boolean done; 

     public void onResult(Integer result) { 
      this.result = result; 
      this.done = true; 
     } 

     public boolean isDone() { 
      return done; 
     } 

     public Integer getResult() { 
      return result; 
     } 
    } 
} 

你也可以使用的CountDownLatch所推薦的哈孔伯爵的回答。它會做基本相同的事情。我還建議你熟悉java.util.concurrent package,以便更好地管理線程。最後,僅僅因爲你可以這是不是一個好主意。如果您正在使用基於異步回調的框架,那麼您可能比試圖顛覆它更有效地學習如何有效地使用框架。

+0

你能提供代碼示例嗎? –

0

,你在網頁的方式來處理:存儲無論是在會議上的一些數據,或者cookies或隱藏字段等等。

就我所知,您嘗試解決的問題並非來自異步,而是來自無狀態的http protocole。

問候, 斯特凡

+0

卓悅,我開發一個Android應用程序。異步是爲了在長時間下載時不破壞用戶體驗。無狀態http協議無關。我仍然想以同步的方式編寫「獲取響應」。 –

1

基本上你需要各種各樣的「聽衆」不管是什麼。這是因爲你不知道什麼時候你的返回消息會回來,如果有的話(這是異步處理的缺點之一......如果你沒有得到返回消息該怎麼辦)。

所以你要麼需要實現一個等待事件的監聽器(即它被返回的消息加以處理)。

或者您可以通過在您的服務上「輪詢」(或拉出)響應區域以查看返回消息是否存在的單獨線程來實現混合。

所以它真的歸結爲是否需要更多的「拉」或「推」檢索消息的方法。

SCA (Service Component Architecture)框架可能是需要考慮的問題,但取決於你在做什麼,它也可能是矯枉過正。但要考慮一些事情。

編輯:

我剛剛發現這個在Java SE 6的Javadoc,可能會有幫助。 接口CompletionService其中關於 - >異步工作摘要您關心的東西 。我建議你看看。

6

難道CountDownLatch對您有幫助嗎?在主要方法中,您調用getResponse然後countDownLatch.await()。通過倒計時鎖存到GETRESPONSE方法,然後倒計數一次GETRESPONSE從GETRESPONSE結果完成:

CountDownLatch latch = new CountDownLatch(1); 
Response a = getResponse(latch); 
latch.await(); 

latch = new CountDownLatch(1); 
Response b = getResponse(latch); 
latch.await(); 

process(a, b); 

你GETRESPONSE需要調用latch.countDown()一旦它的非同步部分返回結果。

例如爲:

public Response getResponse(CountDownLatch latch) { 
    someAsychBloc(final CountDownLatch latch) { 
     do work 
     latch.countDown(); 
    } 
} 
+0

感謝CountDownLatch –

11

首先,你不應該拒絕前兩種方法你商量。人們使用這些技術的原因有很多,您應該嘗試學習,而不是創建新技術。

否則,你應該看看java.util.concurrent

ExecutorService es = Executors.newFixedThreadPool(2); 
... 
Future<Response> responseA = es.submit(responseGetter); 
Future<Response> responseB = es.submit(responseGetter); 

process(responseA.get(), responseB.get()); 

其中responseGetterCallable<Response>類型的(你必須實現的方法public Response call())。

+0

反應良好,我實現了一些代碼。 –

+0

這應該是被接受的答案。使用Thread.sleep並不是一個好習慣。 – Rafaesp