避免阻塞方法以使代码异步

时间:2019-06-26 06:59:35

标签: java asynchronous client-server

如何更改此代码以摆脱线程阻塞?这里的.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) {
            }
        };
    }

我的期望:

  1. 程序在主线程中发送请求。
  2. 然后是一种回调,它在 替代线程。
  3. 仍然,该程序继续在主线程中工作-继续发送更多请求。
  4. 来自服务器的响应到达时,来自服务器的回调 替代线程以某种方式捕获并处理它,但是它 与主线程不匹配

1 个答案:

答案 0 :(得分:0)

您应该在新线程中运行异步任务(最好使用ExecutorService或CompletableFuture)。将CallbackHandler传递给Runnable / Callable任务,并在调用完成后调用处理程序方法。

或者,如果您担心的只是处理异步http请求,我建议您不要重新发明轮子,而是使用现有的解决方案。 Example of async http client

对于其他用例,您可以按照以下示例进行操作。

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");
        }
    }
}