Ray*_*non 17 java asynchronous response request
我从类似的问答中读到了答案
如何在JAVA中创建异步HTTP请求?|
异步编程设计模式 |
AsyncTask Android - 设计模式和返回值
我看到很多解决方案,但没有一个真的让我满意.
倾听者的方式
捕获结果后,处理将在onResult方法中实现.
public interface GeolocationListener {
public void onResult(Address[] addresses);
public void onError(Exception e);
}
Run Code Online (Sandbox Code Playgroud)
这个解决方案并不能让我满意,因为我想在main方法中处理结果.我讨厌这个接口,因为当返回响应时,它会在onResult中处理,导致处理链,无法返回"main"方法.
servlet的方式
public class SignGuestbookServlet extends HttpServlet {
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
// ...
resp.sendRedirect("/guestbook.jsp");
}
}
Run Code Online (Sandbox Code Playgroud)
没有公开的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);
Run Code Online (Sandbox Code Playgroud)
是否有设计模式来处理异步请求并等待上面的响应?其他方式比听众.请不要图书馆或框架.
编辑 感谢到目前为止的回复.我没有给你全部图片所以我暴露了Geolocation类我开始实现.我不知道如何实现该方法.有人能说"怎么样"?他(或她)还必须实现侦听器以检索结果
private Address getFullAddress (String text, AddressListener listener, ... ){
// new Geolocation(text, listener, options).start()
// implements Geolocation.GeolocationListener
// how to return the Address from the onResult ?
}
Run Code Online (Sandbox Code Playgroud)
tot*_*to2 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());
Run Code Online (Sandbox Code Playgroud)
where responseGetter
是类型Callable<Response>
(您必须实现该方法public Response call()
).
异步代码始终可以同步.最简单/最原始的方法是进行异步调用,然后输入一个只停留当前线程的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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
你也可以按照hakon的回答推荐使用CountDownLatch.它基本上会做同样的事情.我还建议你熟悉java.util.concurrent包,以便更好地管理线程.最后,仅仅因为你可以做到这一点并不是一个好主意.如果您正在使用基于异步回调的框架,那么学习如何有效地使用框架比尝试颠覆它更好.
可以CountDownLatch帮你?在main方法中,调用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);
Run Code Online (Sandbox Code Playgroud)
一旦异步部分返回结果,你的getResponse就需要调用latch.countDown().
例如:
public Response getResponse(CountDownLatch latch) {
someAsychBloc(final CountDownLatch latch) {
do work
latch.countDown();
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
22931 次 |
最近记录: |