java - 避免阻塞方法使代码异步
问题描述
如何更改此代码以摆脱线程阻塞?这里.get()
阻塞线程以接收来自未来的结果。但是我可以绝对避免阻塞吗?类似于 - 一个线程发送请求,另一个线程接收响应并实现一些代码。使其完全异步。
我尝试使用 CompletableFuture,但无法真正理解它。试图制作一个回调方法,但也没有成功。
byte[] sendRequest(JSONObject jsonObject, String username, String password) throws IOException, ExecutionException, InterruptedException {
try (AsyncHttpClient client = new AsyncHttpClient()) {
String userPassword;
if (username != null && password != null) {
userPassword = username + ":" + password;
} else {
throw new NullPointerException("Нет логина и/или пароля.");
}
Future future = client.preparePost(apiUrl)
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Basic " + DatatypeConverter.printBase64Binary(userPassword.getBytes()))
.setBody(jsonObject.toString().getBytes())
.execute(getHandler());
String response = (String) future.get();
return response.getBytes();
}
}
private AsyncCompletionHandler<String> getHandler() throws IOException {
return new AsyncCompletionHandler<String>() {
@Override
public String onCompleted(Response response) throws IOException {
return response.getResponseBody();
}
@Override
public void onThrowable(Throwable t) {
}
};
}
我的期望:
- 程序在主线程中发送请求。
- 然后有一种回调,它等待替代线程中的响应。
- 尽管如此,该程序继续在主线程中工作 - 它继续发送更多请求。
- 当来自服务器的响应到来时,来自备用线程的回调会捕获它并以某种方式进行处理,但它与主线程不对应
解决方案
您应该在新线程中运行异步任务(最好使用 ExecutorService 或 CompletableFuture)。将 CallbackHandler 传递给 Runnable/Callable 任务,一旦调用完成,调用处理程序方法。
或者,如果您担心的只是处理异步 http 请求,我建议不要重新发明轮子,而是使用现有的解决方案。异步 http 客户端示例
对于其他用例,您可以按照以下示例进行操作。
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone {
public static void main (String[] args) throws java.lang.Exception {
for (int i=0; i<10; i++) {
new Thread(new MyRunnable(new CallbackHandler())).start();
}
}
static class MyRunnable implements Runnable {
CallbackHandler handler;
public MyRunnable(CallbackHandler handler) {
this.handler = handler;
}
public void run() {
try {
Thread.sleep(100);
} catch(Exception e) {
} finally {
Random r = new Random();
if (r.nextBoolean()) {
handler.onSuccess();
} else {
handler.onError();
}
}
}
}
static class CallbackHandler {
public void onSuccess() {
System.out.println("Success");
}
public void onError() {
System.out.println("Error");
}
}
}
推荐阅读
- dll - 为什么引擎是游戏使用的库?
- mongodb - 可以在 MongoDB 中创建灵活的文档吗?
- java - 我们能否在不影响服务层的情况下处理从 dao 层到表示层的异常(服务层不修改)
- c++ - 通过C++中的remove方法自我删除对象
- java - 你如何在 MacOsx High Sierra 中修复 Javac
- customization - 如何访问 data.home._children 循环中的自定义字段
- java - 如何获取当前时间和日期并设置在我的应用程序中执行操作的特定时间
- python - 关于 Python 中的生成器和迭代器的 3 个问题
- c - while循环中变量变化的问题
- php - PHP 帮助验证集合属性