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

2022-09-01 03:13:50

我有几个线程同时运行,其中一些需要从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

你问了一个非常好的问题,请允许我全面阐述。根据为 OkHttp 打开的 GitBub 问题,我的总结是这样的。

问题

我相信OkHttpClientOkHttpClient.open()'线程安全的单个实例?OkHttpClient should be reused to create multiple connections. Is thread safe? If not, is

是的。它被设计为被视为单例。通过使用单个实例,您可以获得共享响应缓存,线程池,连接重用等。一定要这样做!

问题

线程安全性如何?线程安全还是至少是其功能?OkHttpClientopen()

是的

结论

OkHttpClients 應該是共享的

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


答案 2

推荐