并行调用OkHttpClient是否是线程安全的?

时间:2018-01-31 00:57:06

标签: java android thread-safety okhttp

我有几个同时运行的线程,其中一些需要从Internet请求数据。我是否需要关心他们对OkHttpClient单例的访问权限?

例如,

线程1:

...
Request request = new Request.Builder()
    .url("http://hell.com/siners.txt")
    .build();

client.newCall(request).enqueue(new Callback() {
  @Override public void onFailure(Call call, IOException e) {
    e.printStackTrace();
  }

  @Override public void onResponse(Call call, Response response) throws IOException {
    try (ResponseBody responseBody = response.body()) {
      if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
      // Some work in Thread1
    }
  }

线程2:

...
Request request = new Request.Builder()
    .url("http://hell.com/slutList.txt")
    .build();

client.newCall(request).enqueue(new Callback() {
  @Override public void onFailure(Call call, IOException e) {
    e.printStackTrace();
  }

  @Override public void onResponse(Call call, Response response) throws IOException {
    try (ResponseBody responseBody = response.body()) {
      if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
      // Some work in Thread2
    }
  }

同时newCall()。enque()或newCall()。execute()是否有潜在危险?

1 个答案:

答案 0 :(得分:14)

你问了一个非常好的问题,请允许我从整体上进行阐述。基于为OkHttp打开的github问题,我的总结是这样的。

问题: 我相信应该重用OkHttpClient的单个实例来创建多个连接。 OkHttpClient线程安全吗?如果没有,OkHttpClient.open()线程安全吗?

答案: 是。它被设计为单独处理。通过使用单个实例,您将获得共享响应缓存,线程池,连接重用等。绝对可以这样做!

问题: 线程安全怎么样? OkHttpClient线程是安全的还是至少它的open()函数?

答案: 是

结论:

应该共享OkHttpClients

  

当您创建单个OkHttpClient实例并将其重用于所有HTTP调用时,OkHttp的效果最佳。这是因为每个客户端都拥有自己的连接池和线程池。重用连接和线程可减少延迟并节省内存。相反,为每个请求创建客户端会浪费空闲池上的资源。