首页 > 解决方案 > Retrofit2 parallel requests

问题描述

I'm using OkHttp + Retrofit2 to build an api to a third party system.
I've noticed that even using a ConnectionPool and multiple threads, Retrofit is never making simultaneous calls.

This is how i create the service:

OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
httpClientBuilder.connectionPool(new ConnectionPool(7, 1, TimeUnit.MINUTES););
Dispatcher dispatcher = new Dispatcher();
dispatcher.setMaxRequests(10);
dispatcher.setMaxRequestsPerHost(10);
httpClientBuilder.dispatcher(dispatcher);
OkHttpClient okhttp = httpClientBuilder.build();
this.service = new Retrofit.Builder().baseUrl(API_URL).addConverterFactory(GsonConverterFactory.create(getGson())).client(okhttp).build().create(IService.class);

In order to simplify the IService.class lets supose it has only 2 methods:

@GET
    Call<JsonElement> get(@Url String url, @HeaderMap Map<String, Object> headers, @QueryMap Map<String, Object> query);

        @POST
    Call<ResponseBody> complexPost(@Url String url, @HeaderMap Map<String, Object> headers, @QueryMap Map<String, Object> query, @Body RequestBody body);

now this is how i'm trying to make parallel requests:

public static void main(String[] args) {

    final Map<String,Object> empty = new HashMap<String, Object>();
        new Thread(new Runnable() {

            @Override
            public void run() {
                    while(true) {
                        System.out.println("sending short request");
                        this.service.get(bar,empty,empty).execute();
                        System.out.println("short request sent");
                    }
            }
        }).start();


        new Thread(new Runnable() {

            @Override
            public void run() {
                byte[] buffer  = new byte[1024*1024];

                    while(true) {
                        RequestBody requestFile = RequestBody.create(MediaType.parse("application/octet-stream"), buffer, 0, buffer.length);
                        System.out.println("sending long request");
                        this.service.complexPost(foo, empty, empty, requestFile).execute();
                        System.out.println("long request sent");
                    }
            }
        }).start();

}

Simple explanation: two threads, thread A sends a small GET request - thread B sends 1MB data request [1024*1024 zeros just]

So, nothing is synchronized, I've a connection pool with enough idle connections to make it run in parallel, IN MY MIND sine request B is bigger is natural it takes long to complete the request, but as there is no synchronization there should be LOTS of "short request sent" for every "long request sent".

but what is printed is something like:

sending short request
short request sent  
sending long request
long request sent
sending short request
short request sent
sending long request
long request sent
sending short request
short request sent

no thread is interrupting the other request. WHY???? how to make multiple requests in parallel?

标签: multithreadingretrofitretrofit2okhttp

解决方案


推荐阅读