web-dev-qa-db-fra.com

Est-il thread-safe de faire des appels à OkHttpClient en parallèle?

J'ai plusieurs threads qui s'exécutent en même temps et certains d'entre eux doivent demander des données à Internet. Dois-je me soucier de la synchronisation de leur accès au singleton OkHttpClient?

Par exemple,

Thread1:

...
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
    }
  }

Thread2:

...
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
    }
  }

Est-ce que newCall (). Enque () ou newCall (). Execute () simultanés peuvent être potentiellement dangereux?

21
Dmitrii Demenev

Vous avez posé une très bonne question, permettez-moi d'exposer de manière holistique. Basé sur les problèmes de github ouverts pour OkHttp, mon résumé est le suivant.

Question: Je pense qu'une seule instance d'OkHttpClient devrait être réutilisée pour créer plusieurs connexions. Le thread OkHttpClient est-il sûr? Sinon, le thread OkHttpClient.open () est-il sûr?

Réponse: oui. Il est conçu pour être traité comme un singleton. En utilisant une seule instance, vous disposez d'un cache de réponse partagé, d'un pool de threads, d'une réutilisation de connexion, etc.

Question: qu'en est-il de la sécurité des fils? Le thread OkHttpClient est-il sûr ou au moins sa fonction open ()?

Réponse: oui

Conclusion:

OkHttpClients doit être partagé

OkHttp fonctionne mieux lorsque vous créez une seule instance OkHttpClient et la réutilisez pour tous vos appels HTTP. En effet, chaque client possède son propre pool de connexions et ses propres pools de threads. La réutilisation des connexions et des threads réduit la latence et économise de la mémoire. Inversement, la création d'un client pour chaque demande gaspille des ressources sur des pools inactifs.

19
Remario